interfaces - listas genericas c#
Método genérico de C#sin especificar el tipo (3)
Ok, soy un chico de Java que comienza a usar C # y estaba codificando y comencé a hacer un método genérico y lo que escribí se ejecuta y compila, pero va en contra de todo lo que sé sobre cómo deberían funcionar los genéricos, así que espero que alguien pueda explicarlo. a mi:
Así que tengo un método genérico definido de la siguiente manera:
public static List<T> CopyAsList<T>(IEnumerable<T> list, Object lockObject)
{
if (list != null)
{
lock (lockObject)
{
return new List<T>(list);
}
}
return null;
}
Pero lo más extraño para mí es que puedo llamar a este método genérico sin especificar T
y funcionará:
List<String> strings = new List<string>() { "a", "b", "c"};
List<int> ints = new List<int>() { 1,2,3};
object lockObject = new object();
foreach (string s in CopyAsList(strings, lockObject))
{
Console.WriteLine(s);
}
foreach (int i in CopyAsList(ints, lockObject))
{
Console.WriteLine(i);
}
¿Cómo es posible que el código se compile sin especificar el tipo genérico? ¿C # infiere el tipo en tiempo de ejecución?
C # tiene muchas más funciones de inferencia de tiempo de compilación y tiempo de ejecución que Java. Si este tema le interesa, vea mis artículos sobre el tema:
http://blogs.msdn.com/b/ericlippert/archive/tags/type+inference/
Si está especialmente interesado en la inferencia de tipo de método genérico y tiene media hora de sobra, aquí está explicando cómo cambiamos el algoritmo de inferencia de tipo en C # 3:
http://blogs.msdn.com/b/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx
El compilador de C # a menudo puede inferir el tipo genérico en tiempo de compilación . Cuando puede hacer esto, no necesita especificar el tipo para un método genérico.
Esta es una parte importante de lo que hace a LINQ "utilizable". Sin la inferencia de tipo de tiempo de compilación, las consultas se verían así:
IEnumerable<int> myIds = myCollection
.Where<MyType>(i => i.Name == "Foo")
.Select<MyType, int>(i => i.Id);
En lugar de poder escribir:
var myIds = myCollection.Where(i => i.Name == "Foo").Select(i => i.Id);
No, se deduce en el momento de la compilación: se utiliza el parámetro de tipo genérico en el IEnumerable<T>
usted suministra, lo que se conoce en el momento de la compilación. En general, todo lo que se refiere a los parámetros genéricos y de tipo se especifica en el momento de la compilación. Si hay discrepancia de cualquier tipo, el compilador se quejará y su código no se compilará.
Hay casos de borde en los que tiene que especificar los tipos explícitamente, esto solo ocurre en raras circunstancias con métodos sobrecargados, a veces con múltiples combinaciones de parámetros de tipo.