2014-07-03 6 views
5

Dlaczego nie można wywnioskować właściwego przeciążenia, które można nazwać, w linii oznaczonej // Compiler Error w poniższym kodzie, gdy typ jest poprawnie wywnioskowany we wszystkich pozostałych przypadkach?Dlaczego przekazywanie grupy metod do przeciążonej metody powoduje niejednoznaczność podczas wywoływania metody w lambda, w tym przypadku?

public static class Code { 

    private static void Main() { 

     OverloadedMethod<string>(() => new Wrapper<string>()); // OK 
     OverloadedMethod<string>(() => MethodReturningWrappedString()); // OK 
     OverloadedMethod<string>((Func<Wrapper<string>>)MethodReturningWrappedString); // OK 
     OverloadedMethod<string>(MethodReturningWrappedString); // Compiler Error 

    } 

    public static Wrapper<string> MethodReturningWrappedString() { 
     return new Wrapper<string>(); 
    } 

    public static void OverloadedMethod<T>(Func<Wrapper<T>> func) where T : class { 
    } 

    public static void OverloadedMethod<T>(Func<T> func) where T : class { 
    } 

    public struct Wrapper<T> where T : class { 
    } 

} 

Tutaj błąd kompilator:

The call is ambiguous between the following methods or properties: 
'Namespace.Code.OverloadedMethod<string>(System.Func<Namespace.Code.Wrapper<string>>)' 
and 'Namespace.Code.OverloadedMethod<string>(System.Func<string>)' 

Odpowiedz

2

Ponieważ grupa Sposób MethodReturningWrappedString można przekształcić zarówno pełnomocnik typu Func<Wrapper<T>> i pełnomocnika typu Func<U> do odpowiednich wartości T i U.

Reguły dotyczące przeciążenia nie stanowią, że pierwsza konwersja jest ściśle lepsza niż druga, więc konwersja jest niejednoznaczna i powoduje błąd kompilatora.

+0

Czy lambda "() => MethodReturningWrappedString()" używa różnych reguł? – Craig

+0

Dlaczego więc ogólne ograniczenie "where T: class" brane pod uwagę przy przekazywaniu lambda, ale nie w momencie przekazania grupy metod? –

+0

Ale 'Wrapper ' jest strukturą, więc nie może spełnić 'Func gdzie U: klasa' –