2011-08-24 17 views
11

¿Posible? ¿Puedes cambiar el acceso de cualquier cosa a cualquier cosa más?C# anular miembro público y hacerlo privado

+5

Escribo ese error exacto al menos una vez al día. –

+1

@Phil: No, OP lo deletreó correctamente. ;) – Yuck

+0

wow Nunca lo noté hasta después de haberlo reparado –

Respuesta

14

No, no puede ocultar un miembro del público con un método privado en una subclase, pero no se puede anulación un miembro del público con una privada en una subclase. Y, en realidad, no es solo una cosa pública/privada, esto se aplica a restringir el acceso en general.

revisado: Al ocultar con un acceso más restrictivo - en este caso el acceso privado - le todavía ver el miembro de la clase base desde una clase base o de referencia sub-clase, pero sería ceder ante la nueva método cuando esté disponible desde el nuevo nivel de acceso.

Por lo tanto, en general, cuando se oculta, el cuero tiene prioridad cuando se lo ve en su nivel de acceso. De lo contrario, el método original es el utilizado.

public class BaseClass 
{ 
    public virtual void A() { } 

    public virtual void B() { } 
} 

public class SubClass 
{ 
    // COMPILER ERROR, can't override to be more restrictive access 
    private override void A() { } 

    // LEGAL, you can HIDE the base class method, but which is chosen 
    // depends on level accessed from 
    private new void B() { } 
} 

Así SubClass.B() sólo oculta los métodos de la clase base cuando es accesible. Es decir, si llama al SubClass.B() dentro de SubClass, tomará la forma oculta de B(), pero como B() es privado, no es visible para las clases fuera de sí, y por lo tanto TODAVÍA ver BaseClass.B().

El largo y el corto de él es:

1) No se puede sustituir un método a ser más restrictivas (acceso sabia). 2) Puede ocultar un método con uno más restrictivo, pero solo tendrá un efecto donde ese nuevo tipo de acceso sea visible, de lo contrario, se mantendrá la base.

public class BaseClass 
{ 
    public virtual void A() { } 
    public virtual void B() { } 
} 

public class SubClass : BaseClass 
{ 
    public virtual void A() { B(); } 

    // legal, you can do this and B() is now hidden internally in SubClass, 
    // but to outside world BaseClass's B() is still the one used. 
    private new void B() { } 
} 

// ... 

SubClass sc = new SubClass(); 
BaseClass bc = new BaseClass(); 

// both of these call BaseClass.B() because we are outside of class and can't 
// see the hide SubClass.B(). 
sc.B(); 
bc.B(); 

// this calls SubClass.A(), which WILL call SubClass.B() because the hide 
// SubClass.B() is visible within SubClass, and thus the hide hides BaseClass.B() 
// for any calls inside of SubClass. 
sc.A(); 
+0

¿Estás seguro de eso? Parece que rompería el –

+0

de Liskov. Puedes hacerlo. Sin embargo, podría simplemente lanzarlo a 'BaseClass' y llamar al método como si nada hubiera sucedido. – Femaref

+0

@Brian: Sí, ocultar para hacer más restrictivo está permitido. Compila bien.Recuerde que el método aún existe, y siempre que lo trate como una referencia de clase base, todavía está allí y se ejecuta, simplemente no es visible desde una subclase (en el caso de la ocultación privada). No dice que siempre es la mejor opción, OO sabio, pero es posible en C#. –

3

Nope.

Una forma típica de lidiar con esto es lanzar un NotImplementedException o algo por el estilo.

+6

'NotImplementedException' implica algo omitido por error. 'NotSupportedException' implica algo omitido por diseño (y posiblemente * todavía * por error, según sea el caso). –

2

No puede limitar o ampliar la visibilidad de un miembro anulado. Sin embargo, puede definir otro método con la palabra clave new, que puede darle un nuevo método con el mismo nombre , pero que es incompatible en términos de polimorfismo.

public class A : B 
{ 
    public new void Foo() 
    { 
     base.Foo(); 
    } 
} 
+2

Eso no es un ** viaje **, es una ** escritura **. Si convierte esta clase a 'B', el método estará disponible, aunque lo sobreescribió en' A'. – Femaref

+0

@Femaref Técnicamente correcto, el mejor tipo de derecho. –

Cuestiones relacionadas