2012-01-28 16 views
5

¡Soy un recién llegado al desbordamiento de la pila, así que por favor vaya tranquilo conmigo! Estoy leyendo C# en profundidad, pero me encontré con un escenario que no creo que esté cubierto. Una búsqueda rápida en la web tampoco arrojó ningún resultado.Escriba la inferencia para los argumentos de tipo de los métodos genéricos

Di defino los siguientes métodos sobrecargados:

void AreEqual<T>(T expected, T actual) 

void AreEqual(object expected, object actual) 

Si llamo AreEqual() sin especificar un argumento de tipo:

AreEqual("Hello", "Hello") 

es la versión genérica o no genérico del método invocado? ¿Se invoca el método genérico con el argumento de tipo inferido, o se invoca el método no genérico con los argumentos del método implícitos en System.Object?

Espero que mi pregunta sea clara. Gracias de antemano por cualquier consejo.

+5

por supuesto, puede escribir un código simple para comprobar esto ... –

+1

http://blogs.msdn.com/b/ericlippert/archive/2009/07/30/generics-are-not-templates.aspx –

+0

@Mitch Wheat - cierto, pero entonces no tendría que hacer mi primera publicación. Y es útil para que otros vean la respuesta aquí. – zekesteer

Respuesta

5

Los genéricos pueden generar una función AreEqual(string, string). Esta es una coincidencia más cercana que AreEqual(object, object), por lo tanto, se elige la función genérica.

Curiosamente, el compilador elegirá esta función genérica incluso si da como resultado un error de violación de restricción.

vistazo a este ejemplo:

using System.Diagnostics; 

namespace ConsoleSandbox 
{ 
    interface IBar 
    { 
    } 

    class Program 
    { 
     static void Foo<T>(T obj1) where T: IBar 
     { 
      Trace.WriteLine("Inside Foo<T>"); 
     } 


     static void Foo(object obj) 
     { 
      Trace.WriteLine("Inside Foo Object"); 
     } 

     static void Main(string[] args) 
     { 

      Foo("Hello"); 
     } 
    } 
} 

incluso aquí se elegirá la versión genérica sobre la versión no genérica. Y a continuación, obtiene este error:

The type 'string' cannot be used as type parameter 'T' in the generic type or method 'ConsoleSandbox.Program.Foo(T)'. There is no implicit reference conversion from 'string' to 'ConsoleSandbox.IBar'.

Pero si se agrega una función Foo(string obj1) se ponga a funcionar.

+0

¡Gran respuesta, gracias! Buen ejemplo, lo intenté solo para confirmar :-) – zekesteer

+0

Tenga en cuenta que la resolución de sobrecarga la realiza el compilador C#, no el .NET framework. – phoog

+0

@phoog - gracias, he cambiado la redacción –

Cuestiones relacionadas