2009-05-20 22 views
9

Estoy tratando de crear un conjunto de clases donde un ancestro común es responsable de toda la lógica involucrada en el establecimiento de varias propiedades, y los descendientes simplemente cambian el acceso de las propiedades dependiendo de si se requieren en el descendiente particular.Cómo aumentar el modificador de acceso de una propiedad

Cuando trato de hacerlo como se muestra a continuación me sale un error de compilación: "no se puede cambiar modificadores de acceso Al reemplazar 'protegido' miembro heredado"

¿Hay una manera de lograr lo que estoy tratando de ¿hacer? Gracias

public class Parent 
{ 
    private int _propertyOne; 
    private int _propertyTwo; 

    protected virtual int PropertyOne 
    { 
      get { return _propertyOne; } 
      set { _propertyOne = value; } 
    } 

    protected virtual int PropertyTwo 
    { 
      get { return _propertyTwo; } 
      set { _propertyTwo = value; } 
    } 
} 

public class ChildOne : Parent 
{ 
    public override int PropertyOne // Compiler Error CS0507 
    { 
     get { return base.PropertyOne; } 
     set { base.PropertyOne = value; } 
    } 
    // PropertyTwo is not available to users of ChildOne 
} 

public class ChildTwo : Parent 
{ 
    // PropertyOne is not available to users of ChildTwo 
    public override int PropertyTwo // Compiler Error CS0507 
    { 
     get { return base.PropertyTwo; } 
     set { base.PropertyTwo = value; } 
    } 
} 

Respuesta

11

Usted puede hacer esto mediante el uso de "nueva" en lugar de "anular" para ocultar los bienes protegidos de los padres de la siguiente manera:

public class ChildOne : Parent 
{ 
    public new int PropertyOne // No Compiler Error 
    { 
     get { return base.PropertyOne; } 
     set { base.PropertyOne = value; } 
    } 
    // PropertyTwo is not available to users of ChildOne 
} 

public class ChildTwo : Parent 
{ 
    // PropertyOne is not available to users of ChildTwo 
    public new int PropertyTwo 
    { 
     get { return base.PropertyTwo; } 
     set { base.PropertyTwo = value; } 
    } 
} 
+2

OOPS .. Segundos más rápido :) .. De todos modos el uso de nuevo no es lo mismo que anular; nuevo oculta al miembro padre y de esta manera ya no es polimorfismo. – Galilyou

+0

@ José, gracias que hace lo que necesito. – WileCau

2

NO. Todavía puede ocultar la propiedad heredada con su de

public class ChildTwo: Praent { 
    public new int PropertyTwo { 
     // do whatever you want 
    } 
} 

PD: esto ya no es virtual de relación/anulación (es decir, no hay llamadas polimórficas)

+0

@ 7alwagy, gracias. En mi caso, el virtual/override no importa, solo pensé que lo necesitaba para anular la propiedad base. Usar "nuevo" en lugar de "anular" funciona. – WileCau

5

No se puede cambiar el acceso, pero se puede volver a declarar el miembro con mayor acceso:

public new int PropertyOne 
{ 
    get { return base.PropertyOne; } 
    set { base.PropertyOne = value; } 
} 

el problema es que este es un diferentePropertyOne, y la herencia/virtual podría no funcionar como se espera. En el caso anterior (donde simplemente llamamos al base.*, y el nuevo método no es virtual) probablemente sea correcto. Si necesita verdadero polimorfismo por encima de esto, entonces usted no puede hacerlo (que yo sepa) sin introducir una clase intermedia (ya que no se puede new y override el mismo miembro del mismo tipo):

public abstract class ChildOneAnnoying : Parent { 
    protected virtual int PropertyOneImpl { 
     get { return base.PropertyOne; } 
     set { base.PropertyOne = value; } 
    } 
    protected override int PropertyOne { 
     get { return PropertyOneImpl; } 
     set { PropertyOneImpl = value; } 
    } 
} 
public class ChildOne : ChildOneAnnoying { 
    public new int PropertyOne { 
     get { return PropertyOneImpl; } 
     set { PropertyOneImpl = value; } 
    } 
} 

El punto importante en lo anterior es que todavía hay un solo miembro virtual para anular: PropertyOneImpl.

+0

@Marc, probablemente confundí las cosas porque pensé que necesitaba la virtual/anulación, pero aparentemente en este caso no lo hago. Guardaré un enlace a tu respuesta para cuando necesite hacerlo con polimorfismo :) Gracias por la explicación y el código de muestra. – WileCau

Cuestiones relacionadas