2012-04-23 19 views
6

Supponiamo che io ho un metodo generico come:Come vengono generati i metodi generici in C#?

void Fun<T>(FunArg arg) {} 

Sono this.Fun<Feature> e this.Fun<Category> diverse istanze del metodo generico?

In generale, come viene istanziato il metodo generico? Argomenti generici diversi producono un metodo diverso o lo stesso metodo insieme a metadati diversi che vengono utilizzati in fase di runtime?

Si prega di sostenere la risposta con alcune quote dalla specifica della lingua.

Inoltre, immagino che ho fatto questi:

client.SomeEvent += this.Fun<Feature>; //line1 
client.SomeEvent += this.Fun<Category>; //line2 
client.SomeEvent += this.Fun<Result>; //line3 

poi in seguito,

client.SomeEvent -= this.Fun<Feature>; //lineX 

Condivide la lineX annulla la cosa che ho fatto a line1? O dipende anche da qualcos'altro?

+0

Questo non è un codice valido per iniziare. Non è possibile utilizzare una conversione del gruppo di metodi come destinazione di una dichiarazione 'var'. Presenta codice valido e possiamo dare una risposta migliore. –

+0

@JonSkeet: rimossa quella parte. – Nawaz

+0

Quindi, a questo punto, cosa * esattamente * intendi per "istanziazione"? Più chiaro puoi essere nella tua domanda, più chiara è la tua risposta. –

risposta

4

Dipende dai tipi coinvolti.

Per tutti i tipi di riferimento (es. classi), uno metodo verrà JITted per gestire tutti.

Per tutti i tipi di valore (es. structs), uno metodo per tipo saranno JITted.

Quindi le informazioni nella domanda non sono sufficientemente dettagliate per rispondere, se Feature e Category sono tipi di riferimento, quindi sì, un metodo sarà JITted per loro. Se uno di essi, o entrambi, sono tipi di valore, un metodo per tipo di valore sarà JITted.

Nota il mio uso della parola JITted qui. Nell'assembly compilato, ci sarà un solo metodo, ma in fase di esecuzione, JITter creerà le implementazioni effettive dei metodi generici in base alle regole precedenti.

Pop Quiz: Cosa succede se si utilizza NGEN su un assieme con tipi/metodi generici? (Suggerimento: not what you think)

0

Sì, diventeranno due metodi separati.

+1

Avete qualche fonte per questo? –

+0

Questo aiuto? http://msdn.microsoft.com/en-us/library/twcad0zb(v=vs.80).aspx –

+0

Forse dovrò cancellare questa risposta, perché non stavo guardando troppo da vicino la domanda. –

5

Tutti condividono una definizione di metodo , ma in fase di esecuzione sono diversi MethodInfo - perché gli argomenti di tipo generico definiscono un metodo generico.

illustrazione portante:

Action<FunArg> a1 = Fun<X>; 
    Action<FunArg> a2 = Fun<Y>; 
    Action<FunArg> a3 = Fun<Y>; 
    Console.WriteLine(a1.Method == a2.Method); // false 
    Console.WriteLine(a3.Method == a2.Method); // true 

A livello JIT, è più complessa; qualsiasi parametro di tipo di riferimento sarà condividere un'implementazione, come riferimento è un riferimento è un riferimento (osservando che tutti tali T devono soddisfare eventuali vincoli in anticipo).Se sono presenti il ​​tipo di valore T, ogni combinazione di argomenti di tipo generico ottiene un'implementazione separata in fase di runtime, poiché ciascuno richiede un'implementazione finale diversa.

+0

Non è semplice a livello IL, ma complesso a livello nativo (compilato JIT)? –

+0

@ Jon - anzi; devo amare il codice operativo "vincolato"; Ho usato la frase sbagliata ... –

+0

Ho aggiornato la mia domanda con più domande. Per favore anche quello :-) – Nawaz