Mögliches Duplikat:
Warum ist Func<T> zweideutig mit Func<IEnumerable<T>>?
Ich habe ein sehr merkwürdiges Problem bei der Auflösung von Überlastungen mit Generika festgestellt...
Ziehen Sie die folgenden Methoden in Betracht:
static void Foo<TSource>(TSource element, Func<TSource, int> selector)
{
"int".Dump();
}
static void Foo<TSource>(TSource element, Func<TSource, double> selector)
{
"double".Dump();
}
static T Identity<T>(T value)
{
return value;
}
(C# 4, getestet in LINQPad)
Wenn ich versuche zu telefonieren Foo
mit einem Lambda-Ausdruck als Selektor, funktioniert alles einwandfrei:
Foo(42, x => x); // prints "int"
Aber wenn ich die x => x
con Identity
kann sich der Compiler nicht zwischen den 2 Foo
Überlastungen:
Foo(42, Identity);
// The call is ambiguous between the following methods or properties:
// 'UserQuery.Foo<int>(int, System.Func<int,int>)' and
// 'UserQuery.Foo<int>(int, System.Func<int,double>)'
Wie kann die zweite Überlast ein gültiger Kandidat sein? Die Typinferenz bestimmt korrekt, dass TSource
es int
, so dass die T
Parameter für die Identity
muss die Methode int
auch, daher muss der Rückgabetyp int
auch... Identity
könnte ein Func<int,int>
oder eine Func<double,double>
, aber nicht ein Func<int,double>
!
Und es kommt noch schlimmer! Selbst wenn ich alle Typparameter explizit angebe, erhalte ich immer noch denselben Fehler:
Foo<int>(42, Identity<int>); // The call is ambiguous...
Wie kann es hier irgendeine Zweideutigkeit geben? Soweit ich das beurteilen kann, gibt es keine Möglichkeit, dass die Überladung, die eine Func<int,double>
kann ein Kandidat sein. Ich vermute, die Erklärung muss irgendwo in den Spezifikationen stehen, aber ich kann die entsprechende Stelle nicht finden... oder es könnte ein Fehler im Compiler sein, aber das ist wohl eher unwahrscheinlich.
Beachten Sie, dass es funktioniert, wenn ich den Delegaten explizit erstelle:
Foo(42, new Func<int, int>(Identity)); // prints "int"
Kann mir jemand erklären, was hier vor sich geht? Außerdem: Warum funktioniert es mit einem Lambda, aber nicht mit einer Methodengruppe?