C# metodo generico senza specificare il tipo
-
12-11-2019 - |
Domanda
Ok quindi sono un ragazzo Java che inizia a usare C# e stavo programmando e ho iniziato a creare un metodo generico e ciò che ho scritto tiri e compila, ma va contro tutto ciò che so su come i generici dovrebbero funzionare, quindi spero che qualcuno possa spiegarlo per me:
Quindi ho un metodo generico definito come segue:
public static List<T> CopyAsList<T>(IEnumerable<T> list, Object lockObject)
{
if (list != null)
{
lock (lockObject)
{
return new List<T>(list);
}
}
return null;
}
Ma la cosa strana per me è che posso chiamare questo metodo generico senza mai specificare T
E funzionerà:
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);
}
In che modo il codice è in grado di compilare senza mai specificare il tipo generico? C# deduce il tipo in fase di esecuzione?
Soluzione
No, è dedotto al momento della compilazione - il parametro di tipo generico nel IEnumerable<T>
Viene utilizzato l'offerta, che è noto al momento della compilazione. Generalmente messo, Tutto quanto Per quanto riguarda i parametri generici e di tipo sono specificati al momento della compilazione. Se c'è mancata corrispondenza di qualsiasi tipo, il compilatore volere lamentarsi e il tuo codice non si compilerà.
Esistono casi di bordo in cui è necessario specificare esplicitamente i tipi, questi si verificano solo in rare circostanze con metodi sovraccarichi, a volte con combinazioni multiple di parametri di tipo.
Altri suggerimenti
C# ha molte più caratteristiche di inferenza del tipo di compilazione e di runtime rispetto a Java. Se questo argomento ti interessa, consulta i miei articoli sull'argomento:
http://blogs.msdn.com/b/ericlippert/archive/tags/type+inference/
Se sei in particolare interessato a Inferenza del tipo di metodo generico E hai mezz'ora di riserva, ecco io che spieghi come abbiamo cambiato l'algoritmo di inferenza del tipo in C# 3:
http://blogs.msdn.com/b/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx
Il compilatore C# può spesso dedurre il tipo generico Al momento della compilazione. Quando può farlo, non è necessario specificare il tipo per un metodo generico.
Questa è una parte importante di ciò che rende Linq "utilizzabile". Senza l'inferenza del tipo di tempo di compilazione, le query sarebbero come:
IEnumerable<int> myIds = myCollection
.Where<MyType>(i => i.Name == "Foo")
.Select<MyType, int>(i => i.Id);
Invece di essere in grado di scrivere:
var myIds = myCollection.Where(i => i.Name == "Foo").Select(i => i.Id);