2009-08-10 11 views
7

Considere el siguiente código:¿Qué efecto tiene la palabra clave "nueva" en C# y por qué es solo una advertencia cuando no está empleado?

public abstract class Test1 
{ 
    public object Data { get; set; } 
} 

public abstract class Test2<T> : Test1 
{ 
    public T Data { get; set; } 
} 

Esto generará la siguiente advertencia:

cueros 'Test2.Data' miembro 'Test1.Data' heredado. Usa la nueva palabra clave si te intentabas esconder.

¿Por qué esto es solo una advertencia y qué efecto tendrá la adición de la palabra clave "nueva"?

Según mis pruebas, no puedo encontrar ninguna diferencia una vez que se agrega la palabra clave "nueva".

No me malinterpreten, estoy a favor de ser explícito, pero tenía curiosidad sobre el beneficio de agregar "nuevo".

Mis únicas ideas sobre lo que podría ser son:

  • legibilidad mejorada
  • algún ahorro en tiempo de ejecución cuando el compilador no se deja de entender lo inevitable el camino más largo

Respuesta

21

El único efecto que tiene la palabra clave new es eliminar la advertencia. El propósito de recibir la advertencia cuando no se usa la palabra clave new es evitar que oculte accidentalmente el método cuando realmente quiso anularlo.

2

Active las advertencias de informe como errores. Esto te obligará a ser más explícito con tu uso de nuevo y reemplazar.

3

new se utiliza para ocultar un método o propiedad de la clase base. Esto es no como anulación: el miembro no necesita tener la misma firma que el miembro de clase base oculto y no está involucrado en el polimorfismo.

Un ejemplo:

class A 
{ 
    public virtual void Test() 
    { 
     Console.WriteLine("A.Test"); 
    } 
} 

class B : A 
{ 
    public new void Test() 
    { 
     Console.WriteLine("B.Test"); 
    } 
} 

class B : A 
{ 
    public override void Test() 
    { 
     Console.WriteLine("C.Test"); 
    } 
} 

public static void Main(string[] args) 
{ 
    A aa = new A(); 
    aa.Test(); // Prints "A.Test" 

    A ab = new B(); 
    ab.Test(); // Prints "A.Test" because B.Test doesn't overrides A.Test, it hides it 

    A ac = new C(); 
    ac.Test(); // Prints "C.Test" because C.Test overrides A.Test 

    B b = new B(); 
    b.Test(); // Prints "B.Test", because the actual type of b is known at compile to be B 
} 
+1

nuevo no hace nada (excepto suprimir una advertencia). La ocultación ocurre al omitir la anulación. –

+0

Sí, pero al especificar la palabra clave 'new', oculta explícitamente el miembro. Aunque al final no cambia nada, demuestra que sabes lo que estás haciendo y no olvidó accidentalmente la palabra clave 'anular' –

+0

No, esconderse también sucede sin –

1

si un método de la clase derivada debe considerarse como un reemplazo para un método de la clase base del mismo nombre a menudo depende de si el autor del método de la clase derivada era consciente del método de clase base y su contrato asociado y escribió el método de clase derivada para cumplir con ese contrato. En la mayoría de los casos donde un método de clase derivada tiene el mismo nombre y firma que un método de clase base, el método de clase derivada debería cumplir el contrato de clase base, pero si el autor de una clase base implementada agrega un nombre sin darse cuenta de que el mismo nombre se usa para otro propósito en una clase derivada, no se puede suponer que el autor del método de la clase derivada haya escrito su método para cumplir con el contrato para un método de clase base que no existía en ese momento .

No existe un medio general por el cual el C# pueda decir cuándo se agregaron diferentes métodos a las clases, y por lo tanto el compilador no puede saber si el autor de un método de clase derivada sabía algo sobre la existencia de un nombre del método de clase base a menos que el autor del método de clase derivada indique expresamente al compilador si conoce o no la existencia del método de clase base utilizando los modificadores new o override.

que sugeriría la interpretación de los modificadores (o la falta del mismo) como:

  • Ninguno - El autor no tiene conocimiento de la existencia de un método de la clase base, y por lo tanto no puede estar esperando para cumplir su contrato.

  • new - El autor conoce el método de la clase base y, por cualquier motivo, ha escrito este método para no cumplirlo.

  • override - El autor conoce el método de clase base y su contrato, y escribió este método para completarlo.

La razón por el compilador por defecto a asumir new pero con una advertencia es que en los casos en los que se añada el método a la clase derivada antes alguna vez existió el método de la clase base, el autor no es posible que se espera que hayan sido consciente del contrato de la clase base y no puede haber tenido la intención de cumplir un contrato que aún no existía, pero en los casos en que el método de la clase derivada se escriba después del método de la clase base, el autor generalmente debe elegir otro nombre a menos que el autor tiene la intención de cumplir el contrato de la clase base o tiene una razón específica para usar el mismo nombre sin cumplir el contrato. El compilador no puede decir qué método se escribió primero y, por lo tanto, no tiene forma de saber qué comportamiento es el apropiado.

Cuestiones relacionadas