sirven significado reservadas que para palabras lenguaje instrucciones comandos claves c# syntax override method-hiding

significado - palabras reservadas en c# y para que sirven



C#- uso de palabras clave virtual+reemplazo vs. nuevo (9)

Aquí hay algunos códigos para entender la diferencia en el comportamiento de los métodos virtuales y no virtuales:

class A { public void foo() { Console.WriteLine("A::foo()"); } public virtual void bar() { Console.WriteLine("A::bar()"); } } class B : A { public new void foo() { Console.WriteLine("B::foo()"); } public override void bar() { Console.WriteLine("B::bar()"); } } class Program { static int Main(string[] args) { B b = new B(); A a = b; a.foo(); // Prints A::foo b.foo(); // Prints B::foo a.bar(); // Prints B::bar b.bar(); // Prints B::bar return 0; } }

¿Cuáles son las diferencias entre declarar un método en un tipo base " virtual " y luego reemplazarlo en un tipo secundario usando la palabra clave " override " en lugar de simplemente usar la palabra clave " new " al declarar el método correspondiente en el tipo secundario?


La new palabra clave crea realmente un miembro completamente nuevo que solo existe en ese tipo específico.

Por ejemplo

public class Foo { public bool DoSomething() { return false; } } public class Bar : Foo { public new bool DoSomething() { return true; } }

El método existe en ambos tipos. Cuando utiliza la reflexión y obtiene los miembros del tipo Bar , encontrará 2 métodos llamados DoSomething() que se ven exactamente iguales. Usando new , oculta efectivamente la implementación en la clase base, de modo que cuando las clases derivan de Bar (en mi ejemplo) el método call to base.DoSomething() va a Bar y no a Foo .


La diferencia entre la palabra clave de anulación y la nueva palabra clave es que la primera anula el método y la ocultación del método posterior.

Echa un vistazo a los siguientes enlaces para más información ...

MSDN y Other


La palabra clave "nuevo" no anula, significa un nuevo método que no tiene nada que ver con el método de la clase base.

public class Foo { public bool DoSomething() { return false; } } public class Bar : Foo { public new bool DoSomething() { return true; } } public class Test { public static void Main () { Foo test = new Bar (); Console.WriteLine (test.DoSomething ()); } }

Esto se imprime en falso, si usó anularlo se habría impreso en verdadero.

(Código base tomado de Joseph Daigle)

Por lo tanto, si está haciendo un polimorfismo real, SIEMPRE DEBE ANULAR . El único lugar donde necesita usar "nuevo" es cuando el método no está relacionado de ninguna manera con la versión de clase base.


Más allá de los detalles técnicos, creo que el uso de virtual / override comunica una gran cantidad de información semántica sobre el diseño. Cuando declara un método virtual, indica que espera que las clases de implementación quieran proporcionar sus propias implementaciones no predeterminadas. Omitir esto en una clase base, igualmente, declara la expectativa de que el método predeterminado debería ser suficiente para todas las clases implementadoras. De manera similar, uno puede usar declaraciones abstractas para forzar a las clases de implementación a proporcionar su propia implementación. Una vez más, creo que esto se comunica mucho sobre cómo el programador espera que se use el código. Si escribiera las clases de base y de implementación y me encontrara usando nuevas, seriamente repensaría la decisión de no hacer el método virtual en el padre y declarar mi intención específicamente.


Mi versión de explicación viene del uso de propiedades para ayudar a entender las diferencias.

override es lo suficientemente simple, ¿verdad? El tipo subyacente anula el padre.

new es quizás lo engañoso (para mí lo fue). Con propiedades es más fácil de entender:

public class Foo { public bool GetSomething => false; } public class Bar : Foo { public new bool GetSomething => true; } public static void Main(string[] args) { Foo foo = new Bar(); Console.WriteLine(foo.GetSomething); Bar bar = new Bar(); Console.WriteLine(bar.GetSomething); }

Al usar un depurador, puede observar que Foo foo tiene 2 propiedades GetSomething , ya que en realidad tiene 2 versiones de la propiedad, Foo ''s y Bar '' s, y para saber cuál usar, c # "elige" la propiedad para el tipo actual .

Si quisiera usar la versión de la barra, habría usado anular o utilizar Foo foo lugar.

Bar bar solo tiene 1 , ya que quiere un comportamiento completamente nuevo para GetSomething .


Siempre encuentro cosas como esta más fáciles de entender con fotos:

De nuevo, tomando el código de Joseph Daigle,

public class Foo { public /*virtual*/ bool DoSomething() { return false; } } public class Bar : Foo { public /*override or new*/ bool DoSomething() { return true; } }

Si luego llamas al código así:

Foo a = new Bar(); a.DoSomething();

NOTA: Lo importante es que nuestro objeto es en realidad una Bar , pero lo estamos almacenando en una variable de tipo Foo (esto es similar a lanzarlo)

Luego, el resultado será el siguiente, dependiendo de si usó virtual / override o new al declarar sus clases.


virtual / override le dice al compilador que los dos métodos están relacionados y que en algunas circunstancias, cuando piense que está llamando al primer método (virtual), en realidad es correcto llamar al segundo método (invalidado). Esta es la base del polimorfismo.

(new SubClass() as BaseClass).VirtualFoo()

Llamará al método VirtualFoo () anulado de la SubClase.

new le dice al compilador que está agregando un método a una clase derivada con el mismo nombre que un método en la clase base, pero que no tienen ninguna relación entre sí.

(new SubClass() as BaseClass).NewBar()

Llamará al método NewBar () de BaseClass, mientras que:

(new SubClass()).NewBar()

Llamará al método NewBar () de SubClass.


  • new palabra clave es para ocultar. - significa que estás ocultando tu método en tiempo de ejecución. La salida se basará en el método de clase base.
  • override para anular - significa que está invocando su método de clase derivado con la referencia de la clase base. La salida se basará en el método de clase derivado.