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?

È stato utile?

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);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top