2015-02-24 9 views
21

Mi sono imbattuto in una strana situazione che non è ambigua, tuttavia il risolutore di sovraccarico non la pensa così. Considerare:Perché C# non può risolvere il sovraccarico corretto in questo caso?

public static class Program 
{ 
    delegate int IntDel(); 
    delegate string StringDel(); 

    delegate void ParamIntDel(int x); 
    delegate void ParamStringDel(string x); 

    static void Test(IntDel fun) { } 
    static void Test(StringDel fun) { } 
    static void ParamTest(ParamIntDel fun) { } 
    static void ParamTest(ParamStringDel fun) { } 

    static int X() { return 42; } 
    static void PX(int x) { } 

    public static void Main(string[] args) 
    { 
     ParamTest(PX); // OK 
     Test(X); // Ambiguos call! 
    } 
} 

Come mai la chiamata a ParamTest sovraccarichi viene risolto correttamente, ma Test sovraccarico è ambigua?

+7

Il tipo di ritorno di un metodo non viene considerato quando il compilatore seleziona un sovraccarico. Una conseguenza automatica di non dover effettivamente utilizzare il valore restituito quando si chiama un metodo. Risolto banalmente qui, basta usare 'Test (nuovo IntDel (X));' –

+0

Credo che questo sia vero anche per Java e C++. Tuttavia non è una limitazione fondamentale del polimorfismo parametrico, ad esempio in Haskell è possibile sovraccaricare in base al tipo di ritorno. Il problema è che consentire l'overloading del tipo restituito può causare alcuni problemi con l'inferenza di tipo. – Bakuriu

+2

Offtopic: Mi piace come quasi tutte le domande otterranno almeno un voto ravvicinato in questi giorni. XD –

risposta

37

Forse perché https://msdn.microsoft.com/en-us/library/aa691131%28v=vs.71%29.aspx

La firma di un metodo specifico non include il tipo di ritorno, né include il modificatore params che può essere specificato per il parametro più a destra.

E l'unica differenza tra IntDel e StringDel è nel valore di ritorno.

In particolare: https://msdn.microsoft.com/en-us/library/ms173171.aspx

Nel contesto di overloading dei metodi, la firma di un metodo non include il valore di ritorno. Ma nel contesto dei delegati, la firma include il valore restituito. In altre parole, un metodo deve avere lo stesso tipo di ritorno del delegato.

+0

Accetta in arrivo in 8 minuti e contando ... –

+0

@ Vilx- Aggiunto un altro riferimento che parla esplicitamente di overloading dei metodi con i delegati. – xanatos

+0

Come 'int X()' può essere considerato come 'IntDel' e' StringDel'? –

Problemi correlati