2012-03-28 34 views
12

¿Cómo evito que un método sea anulado en una clase derivada?Cómo evitar que se anule un método en C#

En Java podría hacer esto utilizando el modificador final en el método que deseo evitar que se anule.

¿Cómo logro lo mismo en C#?
Soy consciente de usar sealed pero aparentemente solo puedo usarlo con la palabra clave override?

class A 
{ 
    public void methodA() 
    { 
     // Code. 
    } 

    public virtual void methodB() 
    { 
     // Code. 
    } 
} 

class B : A 
{ 
    sealed override public void methodB() 
    { 
     // Code. 
    } 
} 

Así en el ejemplo anterior que puede evitar que el methodB() que se cambie por cualquier clases derivadas de la clase B, pero ¿cómo puedo evitar clase B anule la methodB() en el primer lugar?

Actualización: Fallé la palabra clave virtual en la declaración methodB() en la clase A cuando publiqué esta pregunta. Corregido.

+0

¿Es esta una nueva característica en C# 4 para sellar un método? –

+0

Si ya no está anulando el método, simplemente no lo decore con 'virtual', entonces todo lo que venga no será considerado para el enlace de métodos en su tipo. –

+0

Creo que sus métodos en la clase A deberían ser 'virtuales' si planea anularlos. – CAbbott

Respuesta

21

Usted no necesita hacer nada. El modificador virtual especifica que un método puede ser anulado. Omitirlo significa que el método es 'final'.

Específicamente, un método debe ser virtual, abstract o override para que se anule.

El uso de la palabra clave new permitirá que el método de la clase base que se oculta, pero todavía no anularlo es decir, cuando se llama a A.methodB() obtendrá la versión de la clase base, pero si se llama a B.methodB() obtendrá la nueva versión.

+0

Es frustrante en un lenguaje que permite que muchas cosas se expliquen explícitamente, no hay una palabra clave para decir explícitamente "esto no significa que nunca se anulará". ", solo para que no accidentalmente lo haga virtual más adelante sin considerar por qué no estaba en primer lugar. –

11

Como usted ha mencionado, se puede evitar más primordial de MethodB en clase B mediante el uso de sealedconoverride

class B : A 
{ 
    public sealed override void methodB() 
    { 
     Console.WriteLine("Class C cannot override this method now"); 
    } 
} 

Uso de la sealed modificador junto conoverride impide una clase derivada de imperiosas aún más la método.

Si no desea que methodB en la clase A sea anulado por cualquier clase secundaria, no marque ese método virtual. Simplemente quítalo. palabra reservada virtual habilitar el método que se reemplaza en las clases hijas

public void methodA() 
{  
} 

Uso sealed de palabras clave en sus clases para prevenir más preponderante de la clase

+3

El uso del modificador sellado impide que una clase derive de la 'clase A'. Eso no es lo que se pidió. –

+0

@KendallFrey: El título de la pregunta me hizo pensar que se trata de evitar una anulación mayor. Gracias – Shyju

+7

@KendallFrey 'sealed' se puede aplicar a los métodos, siempre que también sean anulaciones. Impide * más * anulación en las clases derivadas (como señala Shyju). – dlev

1

En una clase base, la palabra clave sellada solo se usa para evitar que una clase se derive, pero en las clases heredadas se puede usar para evitar que otra clase heredada anule el método.

Para evitar que un método de clase base sea anulado, simplemente no lo especifique como virtual. En el ejemplo que proporcionó, la clase B no pudo anular methodB porque methodB no se marcó como virtual en la clase original.

este compilará:

class A 
{ 
    public virtual void methodA() 
    { 
     //code 
    } 
    public virtual void methodB() 
    { 
     //code 
    } 
} 
class B:A 
{ 
    public override void methodB() 
    { 
     //code 
    } 
} 

esto no:

class A 
{ 
    public void methodA() 
    { 
     //code 
    } 
    public void methodB() 
    { 
     //code 
    } 
} 
class B:A 
{ 
    public override void methodB() 
    { 
     //code 
    } 
} 

Editted: aclarado y corregido mi declaración original sobre el sellado de palabras clave

+2

'sealed' se puede usar en métodos individuales, es solo que' sealed' no se puede usar en la implementación de más alto nivel del método; se debe utilizar en un método que sea una anulación de una implementación base, básicamente anulando la palabra clave "virtual" de los niveles de herencia superiores cuando se deriva aún más. Entonces, estás equivocado de que no se puede usar pero de todos modos no resuelve su problema – KeithS

+0

@KeithS gracias por eso. Nunca lo vi usar para sellar y anular el método antes, pero gracias por enseñarme algo nuevo. He editado mi respuesta de manera apropiada – psubsee2003

5

En C#, una función no marcada virtual (que también incluye anulaciones de funciones virtuales) está efectivamente sellado y no puede ser anulado. Por lo tanto, su código de ejemplo en realidad no compilará porque la palabra clave de anulación no es válida a menos que haya un método marcado como virtual con la misma firma en una clase base.

Si A.methodB() se marcaron como virtuales, puede anular el método de A, pero puede evitar que se anule más en las clases que derivan más indirectamente, usando la palabra clave sealed exactamente como lo ha mostrado.

Una cosa a tener en cuenta es que, aunque se puede evitar la anulación de métodos, el método que oculta no puede. Dada su actual definición de la clase A, la siguiente definición de la clase B es legal y no hay nada que pueda hacer al respecto:

class B:A 
{ 
     public new void methodB() 
      { 
        //code 
      } 
    } 

El new palabra clave, básicamente, "rompe" la herencia/anulando jerarquía en lo que respecta a éste método; cualquier referencia a una clase B, tratada como una clase B (o cualquier otro tipo derivado) usará la implementación de la clase B e ignorará la de la clase A a menos que la implementación de B específicamente le devuelva la llamada. Sin embargo, si tratara una instancia de la clase B como clase A (fundiéndola o pasándola como parámetro), entonces se ignora la implementación "nueva".

Esto difiere de la anulación, donde una clase B que está siendo tratada como una clase A y realmente anula un método virtualB todavía usaría la anulación de clase B del método. También comprenda que se oculta el método de ocultación (aunque obtendrá una advertencia del compilador); si declara un método con la misma firma en una clase derivada y no especifica ni nueva ni anulación, el método de la clase base estará oculto.

+0

Gran información sobre el modificador 'new'. Ni siquiera sabía sobre eso. – CAbbott

Cuestiones relacionadas