¿Cuáles son las diferencias entre declarar un método en un tipo base " virtual" y luego anularlo en un tipo secundario usando la overridepalabra clave " " en lugar de simplemente usar la newpalabra clave " " al declarar el método coincidente en el tipo secundario?
c#
syntax
overriding
method-hiding
member-hiding
i3ensays
fuente
fuente

newcrea un nuevo miembro con el mismo nombre y hace que el miembro original se oculte, mientrasoverrideextiende la implementación para un miembro heredado"Respuestas:
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.
Esto imprime falso, si usó anulación, se habría impreso verdadero.
(Código base tomado de Joseph Daigle)
Entonces, si estás haciendo un verdadero polimorfismo, DEBES ANULAR SIEMPRE . El único lugar donde necesita usar "nuevo" es cuando el método no está relacionado de ninguna manera con la versión de la clase base.
fuente
virtualen la base yoverrideen derivado? ¿Por qué existe? El código aún se ejecutará incluso sin /new¿entonces, es puramente legible?Siempre encuentro cosas como esta más fáciles de entender con imágenes:
Nuevamente, tomando el código de Joseph Daigle,
Si luego llama al código de esta manera:
NOTA: Lo importante es que nuestro objeto es en realidad un
Bar, pero lo estamos almacenando en una variable de tipoFoo(esto es similar a lanzarlo)Entonces el resultado será el siguiente, dependiendo de si usó
virtual/overrideonewal declarar sus clases.fuente
Aquí hay un código para comprender la diferencia en el comportamiento de los métodos virtuales y no virtuales:
fuente
newpara "ocultar" el método base, cuando simplemente no usar anulación parece hacer lo mismo?virtualy el compilador se quejará si ve el mismo nombre de función en una clase "línea de sangre" sinvirtualfirmaLa
newpalabra clave realmente crea un miembro completamente nuevo que solo existe en ese tipo específico.Por ejemplo
El método existe en ambos tipos. Cuando usa la reflexión y obtiene los miembros de tipo
Bar, en realidad encontrará 2 métodos llamadosDoSomething()que se ven exactamente iguales. Al usarlonew, oculta efectivamente la implementación en la clase base, de modo que cuando las clases se derivanBar(en mi ejemplo), la llamada al métodobase.DoSomething()vaBary noFoo.fuente
virtual / override le dice al compilador que los dos métodos están relacionados y que, en algunas circunstancias, cuando crees que estás llamando al primer método (virtual), en realidad es correcto llamar al segundo método (anulado). Este es el fundamento del polimorfismo.
Llamará al método anulado VirtualFoo () 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 relación entre sí.
Llamará al método NewBar () de BaseClass, mientras que:
Llamará al método NewBar () de la Subclase.
fuente
Más allá de solo los detalles técnicos, creo que el uso de virtual / override comunica mucha 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, asimismo, declara la expectativa de que el método predeterminado debería ser suficiente para todas las clases de implementación. Del mismo modo, se pueden usar declaraciones abstractas para forzar la implementación de clases para proporcionar su propia implementación. Nuevamente, creo que esto comunica mucho acerca de cómo el programador espera que se use el código. Si escribiera tanto las clases básicas como las de implementación y me encontrara usando nuevas, volvería a pensar seriamente en la decisión de no hacer que el método sea virtual en los padres y declare mi intención específicamente.
fuente
La diferencia entre la palabra clave de anulación y la nueva palabra clave es que la primera anula el método y la segunda oculta el método.
Consulte los siguientes enlaces para obtener más información ...
MSDN y otros
fuente
newLa palabra clave es para ocultar. - significa que está ocultando su método en tiempo de ejecución. La salida se basará en el método de la clase base.overridepara anular. - significa que está invocando su método de clase derivada con la referencia de la clase base. La salida se basará en el método de clase derivada.fuente
Mi versión de la explicación proviene del uso de propiedades para ayudar a comprender las diferencias.
overridees lo suficientemente simple, ¿verdad? El tipo subyacente anula el del padre.newes quizás el engañoso (para mí lo fue). Con propiedades es más fácil de entender:Al usar un depurador puede notar que
Foo footiene 2GetSomethingpropiedades, ya que en realidad tiene 2 versiones de la propiedad,Foo'syBar', y para saber cuál usar, c # "selecciona" la propiedad para el tipo actual.Si quisieras usar la versión de la barra, hubieras usado anular o usar
Foo fooen su lugar.Bar bartiene solo 1 , ya que quiere un comportamiento completamente nuevo paraGetSomething.fuente
No marcar un método con nada significa: vincular este método utilizando el tipo de compilación del objeto, no el tipo de tiempo de ejecución (enlace estático).
Marcar un método con
virtualmedios: enlace este método utilizando el tipo de tiempo de ejecución del objeto, no el tipo de tiempo de compilación (enlace dinámico).Marcar un
virtualmétodo de clase base conoverrideen clase derivada significa: Este es el método a vincular utilizando el tipo de tiempo de ejecución del objeto (enlace dinámico).Marcar un
virtualmétodo de clase base connewen clase derivada significa: Este es un método nuevo, que no tiene relación con el que tiene el mismo nombre en la clase base y debe vincularse usando el tipo de tiempo de compilación del objeto (enlace estático).No marcar un
virtualmétodo de clase base en la clase derivada significa: Este método está marcado comonew(enlace estático).Marcar un método
abstractsignifica: Este método es virtual, pero no declararé un cuerpo para él y su clase también es abstracta (enlace dinámico).fuente