2011-02-12 14 views
16

Ok, quindi io sono un ragazzo Java di iniziare a utilizzare C# ed ero codifica e iniziato a fare un metodo generico e quello che ho scritto corre e compila ma va contro tutto quello che so su come farmaci generici dovrebbero funzionare così sto sperando che qualcuno può spiegare questo a me:C# metodo generico senza specificare Tipo

così 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); 
} 

Come è possibile che il codice è in grado di compilare, senza mai specificare il tipo generico? C# deduce il tipo in fase di esecuzione?

+6

non c'è C# più in fase di esecuzione. – Gabe

+0

Il compilatore C# deduce il tipo in fase di compilazione. Da una nota a margine, il CLR (DLR) può inferire il tipo in fase di esecuzione, vedere la parola chiave 'dynamic' da C#. – kizzx2

+1

kizzx2: L'OP etichettato la questione con '.net-3.5' che elimina' dynamic' dal contesto, e in fase di esecuzione non v'è alcun tipo di inferenza - DLR utilizza la riflessione per determinare i tipi. – Gabe

risposta

35

No, viene dedotto in fase di compilazione: viene utilizzato il parametro di tipo generico nello IEnumerable<T> fornito dall'utente, che è noto al momento della compilazione. Generalmente put, tutto il riguardante generici e parametri di tipo è specificato al momento della compilazione. In caso di mancata corrispondenza di qualsiasi tipo, il compilatore si lamenterà e il tuo codice non verrà compilato.

Ci sono casi limite in cui si deve specificare i tipi in modo esplicito, questi si verifica solo in rare circostanze con metodi di overload, a volte con molteplici combinazioni di parametri di tipo.

+0

Una di queste circostanze è quando qualsiasi argomento di un metodo viene digitato dinamicamente - una volta che lo si inserisce, tutte le inferenze di tipo generico del compilatore sono fuori dalla finestra, anche se ci sono tutti gli stessi indizi. –

11

Il compilatore C# può spesso dedurre il tipo generico in fase di compilazione. Quando può farlo, non è necessario specificare il tipo per un metodo generico.

Questa è una parte importante di ciò che rende LINQ "utilizzabile". Senza di compilazione tipo di tempo l'inferenza, le query sarà simile:

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); 
+3

e le query con tipi anonimi sarebbero impossibili, inoltre, se il tipo non fosse deducibile dal compilatore, il codice non verrà compilato. – Femaref

+0

Senza l'inferenza del tipo, il compilatore non saprebbe che tipi avrebbero avuto quei lambda. – Gabe

12

C# ha un grande molti di più a tempo di compilazione e le caratteristiche di inferenza di tipo runtime di Java. Se questo argomento vi interessa, vedere i miei articoli sul tema:

http://blogs.msdn.com/b/ericlippert/archive/tags/type+inference/

Se sono in particolare interessati a tipo metodo generico inferenza e si dispone di una mezz'ora di anticipo, ecco mi spiegare come abbiamo cambiato l'algoritmo di inferenza di tipo in C# 3:

http://blogs.msdn.com/b/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx

+0

"caratteristiche di inferenza del tipo runtime" Di quali caratteristiche stai parlando? Qualcosa relativo a 'dinamico'? – CodesInChaos

+0

@CodeInChaos: Sì, "dinamico" in C# significa "elaborare l'analisi del tipo di questa espressione in fase di esecuzione, non in fase di compilazione". –

+0

Sono consapevole di cosa 'dinamico' fa. Volevo solo sapere se stavi parlando di qualche inferenza di tipo runtime al di fuori della funzione 'dinamica'. – CodesInChaos