2012-03-28 13 views
6

he simplificado mi código para estaclase derivada utilizando el método equivocado

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     Child d = new Child(); 
     int i = 100; 
     d.AddToTotal(i); 

     Console.ReadKey(); 
    } 

    private class Parent 
    { 
     public virtual void AddToTotal(int x) 
     { 
      Console.WriteLine("Parent.AddToTotal(int)"); 
     } 
    } 

    private class Child : Parent 
    { 
     public override void AddToTotal(int number) 
     { 
      Console.WriteLine("Child.AddToTotal(int)"); 
     } 

     public void AddToTotal(double currency) 
     { 
      Console.WriteLine("Child.AddToTotal(double)"); 
     } 
    } 
} 

La cuestión es que esto requiere

public void AddToTotal(double currency) 

aunque yo estoy llamando con un int y se debería usar

public override void AddToTotal(int number) 

El uso del elemento primario devuelve el resultado esperado.

Parent d = new Child(); 
int i = 100; 
d.AddToTotal(i); 

Actualización:

Gracias a @Jan y @azyberezovsky por dirigirme a la specification. He agregado un método virtual vacío a la clase base para solucionar esto por el momento.

+2

Bueno, yo era capaz de replicar los resultados, y asegurarse de que no era sólo un error tipográfico en el que el nombre del método de la sobrecarga int era diferente. – Servy

+1

'd.AddToTotal (número: i)' llama a la sobrecarga int, como se esperaba, pero no debería tener que hacer eso ... – Servy

+3

Consulte esta respuesta para obtener una explicación: http://stackoverflow.com/a/1833268/25727 – Jan

Respuesta

8

A member lookup de un nombre de N en un tipo T se procesa como sigue:

En primer lugar, el conjunto de todos los miembros accesibles nombradas N declaradas en T y los tipos de base de T se construye. Las declaraciones que incluyen un modificador anula son excluidas del conjunto. Si no existen miembros con nombre N y son accesibles, la búsqueda no produce coincidencias y los siguientes pasos no se evalúan.

Por lo tanto cuando se utilice variable de tipo infantil

Child d = new Child(); 
int i = 100; 
d.AddToTotal(i); 

método public override void AddToTotal(int number) se excluye del conjunto, y tenemos sólo un método con el nombre N izquierdo. Int se convierte implícitamente en el doble, por lo que no se produjeron errores.

+0

Me resulta muy extraño que la resolución de sobrecarga daría una mayor prioridad a los nuevos métodos sobre los métodos anulados, pero aparentemente es ... extraño. ¿Alguien sabe cuál es el razonamiento detrás de eso? – Servy

+1

@Servy vea esta respuesta de Eric Lippert por el siguiente razonamiento: http://stackoverflow.com/a/1833866/53777 –

+4

@Servy: a muchas personas les resulta extraña esta opción, pero hay dos muy buenas razones para ello. La primera razón es que * el desarrollador que escribió el método de clase derivado tenía más información que el desarrollador que escribió el método de clase base. * Específicamente, el desarrollador de clase derivado sabe cuáles son los detalles de implementación de la clase derivada, pero el desarrollador de clase base no. La resolución de sobrecarga debe elegir el método escrito por el tipo que más sabe sobre el objeto que el usuario está usando realmente. –

1

This answer a this question explica las razones técnicas por las que esto sucede. He incluido la respuesta en línea aquí por conveniencia, pero todo el crédito se debe a tvanfosson.

están en la sección de la Especificación C# Language en Member Lookup y Overload Resolution. El método de sustitución de la clase derivada no es un candidato debido a las reglas de Búsqueda de miembros y el método de clase base no es la mejor coincidencia basada en las reglas de Resolución de sobrecarga .

Sección 7,3

En primer lugar, se construye el conjunto de todos (Sección 3.5) miembros accesibles nombradas N declarada en T y los tipos de bases (Sección 7.3.1) de T. Las declaraciones que incluyen un modificador de anulación se excluyen del conjunto . Si no existen miembros con nombre N y son accesibles, la búsqueda no produce coincidencias y los siguientes pasos no se evalúan.

Sección 7.4.2:

Cada uno de estos contextos define el conjunto de los miembros de función candidatos y la lista de argumentos en su propia manera única, como se describe en detalle en las secciones mencionadas anteriormente. Por ejemplo, el conjunto de candidatos para una invocación a un método no incluye los métodos marcados anulada (Sección 7.3), y los métodos en una clase base no son candidatos si cualquier método en una clase derivada es aplicable (Sección 7.5.5.1) (el énfasis es mío)

Cuestiones relacionadas