¿Cuál es la diferencia entre sombrear y anular un método en C #?
100
Bueno herencia ...
suponga que tiene estas clases:
class A {
public int Foo(){ return 5;}
public virtual int Bar(){return 5;}
}
class B : A{
public new int Foo() { return 1;} //shadow
public override int Bar() {return 1;} //override
}
entonces cuando llames a esto:
A clA = new A();
B clB = new B();
Console.WriteLine(clA.Foo()); // output 5
Console.WriteLine(clA.Bar()); // output 5
Console.WriteLine(clB.Foo()); // output 1
Console.WriteLine(clB.Bar()); // output 1
//now let's cast B to an A class
Console.WriteLine(((A)clB).Foo()); // output 5 <<<-- shadow
Console.WriteLine(((A)clB).Bar()); // output 1
Suponga que tiene una clase base y usa la clase base en todo su código en lugar de las clases heredadas, y usa shadow, devolverá los valores que devuelve la clase base en lugar de seguir el árbol de herencia del tipo real del objeto.
Espero tener sentido :)
El sombreado es en realidad el lenguaje de VB para lo que llamaríamos ocultar en C #.
A menudo, la ocultación (sombreado en VB) y la anulación se muestran como en la respuesta de Stormenet .
Se muestra que un método virtual es anulado por una subclase y las llamadas a ese método incluso en el tipo de superclase o desde el código interno de la superclase llamarán a la implementación de reemplazo desde la subclase.
Luego, se muestra un método concreto (uno no marcado como virtual o abstracto) que se oculta mediante el uso de la
new
palabra clave al definir un método con una firma idéntica en la subclase. En este caso, cuando se llama al método en el tipo de superclase, se utiliza la implementación original, la nueva implementación solo está disponible en la subclase.Sin embargo, lo que a menudo se pasa por alto es que también es posible ocultar un método virtual.
Tenga en cuenta que en el ejemplo anterior DoStuff se vuelve concreto y no se puede anular. Sin embargo, también es posible utilizar las palabras clave
virtual
ynew
juntas.Tenga en cuenta que a pesar de que todos los métodos involucrados son virtuales, la anulación en C no afecta el método virtual en A porque el uso de
new
en B oculta la implementación de A.Editar: se señaló en los comentarios a esta respuesta que lo anterior puede ser peligroso o al menos no particularmente útil. Yo diría que sí, puede ser peligroso y estaría ahí fuera si fuera útil.
En particular, podría meterse en todo tipo de problemas si también cambia los modificadores de accesibilidad. Por ejemplo:-
Para un heredero externo de
Bar
,Foo
la implementación de Thing () sigue siendo accesible y anulable. Todo legal y explicable de acuerdo con las reglas de tipo .NET, nunca menos bastante poco intuitivo.He publicado esta respuesta para profundizar la comprensión de cómo funcionan las cosas, no como una sugerencia de técnicas que se pueden usar libremente.
fuente
Creo que la principal diferencia es que con el sombreado, esencialmente estás reutilizando el nombre y simplemente ignorando el uso de superclase. Con la invalidación, está cambiando la implementación, pero no la accesibilidad y la firma (por ejemplo, tipos de parámetros y retorno). Consulte http://www.geekinterview.com/question_details/19331 .
fuente
El sombreado es un concepto de VB.NET. En C #, el sombreado se conoce como ocultación. Oculta el método de la clase derivada. Se logra usando la palabra clave 'nueva'.
La palabra clave Override se usa para proporcionar una implementación completamente nueva de un método de clase base (que está marcado como 'Virtual') en la clase derivada.
fuente
Básicamente, si tiene algo como a continuación,
Cualquier método que llame al objeto 'a' se hará en el tipo de 'a' (aquí el tipo es 'A') Pero si implementa el mismo método en la clase B que ya está presente en la Clase A, el compilador darle una advertencia para que utilice una palabra clave "Nueva". Si usa "Nuevo", la advertencia desaparecerá. Aparte de esto, no hay diferencia entre usar "Nuevo" o no usarlo en la clase heredada.
En algunas situaciones, es posible que deba llamar a un método de la clase de referencia que contiene la instancia particular en ese momento en lugar de llamar a un método en el tipo de objeto. En el caso anterior, la referencia que contiene es 'B', pero el tipo es 'A'. Entonces, si desea que la llamada al método ocurra en 'B', entonces use Virtual y anule para lograr esto.
Espero que esto ayude...
Daniel Sandeep.
fuente
Si hay un caso en el que no puede alterar el contenido de una clase, digamos
A
, pero desea usar algunos de sus métodos y tiene un método cuyo nombre es común, puede usar su propia implementación de método mediante lanew
palabra clave.El punto crucial es usarlo que tanto la referencia como el objeto deben ser del mismo tipo.
fuente