2015-10-01 19 views
21

Perché il metodo generico viene chiamato quando entrambi i sovraccarichi corrispondono?Quale sovraccarico del metodo C# viene scelto?

public static void method1(object obj) 
{ 
    Console.WriteLine("Object"); 
} 

public static void method1<T>(T t) 
{ 
    Console.WriteLine("Type T"); 
} 

public static void Main(String args[]) 
{ 
    method1("xyz"); //Will print "Type T"; 
} 

Qui non dovrebbero esserci conflitti, giusto?

+0

Simile a [questa domanda] (http://stackoverflow.com/questions/9017363/ambiguous-method-overloading) – adelphus

risposta

36

I sovraccarichi vengono risolti scegliendo il sovraccarico più specifico. In questo caso, method1<string>(string) è più specifico di method1(object), quindi è il sovraccarico scelto.

Ci sono dettagli in section 7.4.2 of the C# specification.

Se si desidera selezionare un sovraccarico specifico, è possibile farlo mediante la trasmissione esplicita dei parametri ai tipi desiderati. Di seguito chiamerà il method1(object) di sovraccarico al posto del generico uno:

method1((object)"xyz"); 

Ci sono casi in cui il compilatore non sapere che sovraccaricano per selezionare, ad esempio:

void method2(string x, object y); 
void method2(object x, string y); 

method2("xyz", "abc"); 

In questo caso il compilatore non sa quale sovraccarico scegliere, perché né il sovraccarico è chiaramente migliore dell'altro (non sa quale stringa implicitamente abbattuta verso l'oggetto). Quindi emetterà un errore del compilatore.

10

C# sceglierà sempre il metodo più specifico possibile.

Quando si compila

method1("xyz"); 

cercherà tutti i metodi con il nome specificato e poi tenta di far corrispondere i parametri. Il compilatore sceglierà il metodo che è il più specifico, in questo caso si preferisce

method1(string s) 

oltre

method1<T>(T t) with T = string 

ed infine

method1(object o) 

Si prega di notare @ eccellente risposta di Erik per un esempio in cui il compilatore non riesce a decidere.

+0

Non cerca 'method1 (string s)' guarda i metodi con lo stesso il nome quindi determina la migliore corrispondenza. – juharr

+0

@juharr Hai ragione, lasciami pulire la mia risposta un po ' – Vlad274

+0

Hai ancora bisogno di rimuovere la parte 'method1 (string s)'.Preferisco il metodo ' (T t)' su 'metodo1 (oggetto o)' – juharr

2

Poiché si sta già passando a T come parametro in modo da non dover digitare method1<string>("xyz");, è sufficiente andare su method1("xyz");, .Net sa già che si tratta di una stringa. Se avessi metodo1, allora sarebbe una storia diversa.

Anche perché method1(object obj) non prende in una stringa come parametro di essa favorirà la funzione generica prima dove può dedurre T. Se si dovesse cambiare method1(object obj)-method1(string obj) sarebbe favorirla prima poi il generico.

+0

Beh, in realtà è il compilatore C# che implementa il tipo generico inferenza; p non ha niente a che fare con .net –

Problemi correlati