Typ des bedingten Ausdrucks kann nicht bestimmt werden (Func)

Beim Zuweisen einer Methode zu einem Func Typ Func ich den Kompilierungserrors. Der Type of conditional expression cannot be determined because there is no implicit conversion between 'method group' and 'method group' .

Das passiert nur mit dem ? : ? : Betreiber Der Code:

 public class Test { public static string One(int value) { value += 1; return value.ToString(); } public static string Two(int value) { value += 2; return value.ToString(); } public void Testing(bool which) { // This works Func actionWorks; if (which) actionWorks = One; else actionWorks = Two; // Compilation error on the part "One : Two" Func action = which ? One : Two; } } 

Ich habe einige Informationen über die Ko- und Kontravarianz gefunden, aber ich sehe nicht, wie sich dies auf die obige Situation bezieht. Warum funktioniert das nicht?

Sie müssen die Signatur mindestens einer Methodengruppe explizit angeben. Danach erlaubt Ihnen der Compiler, die action als implizit typisiertes lokales zu deklarieren:

 var action = which ? (Func)One : Two; 

Der Grund dafür ist, dass der zurückgegebene Typ des operator ?: Nicht basierend auf dem, was Sie ihm zuweisen möchten, sondern aus den Typen der beiden Ausdrücke abgeleitet wird. Wenn die Typen gleich sind oder eine implizite Konvertierung zwischen ihnen vorliegt, leitet der Compiler den Rückgabetyp erfolgreich ab. Andernfalls wird beanstandet, dass keine Konvertierung erfolgt.

Wenn Sie einem Delegaten eine function direkt zuweisen, konvertiert der Compiler die function in den erforderlichen Delegattyp, wenn er mit der Signatur übereinstimmt.

Wenn Sie den Operator?: Verwenden, weisen Sie dem Compiler jedoch nicht zu, dass er einem Delegierten direkt zugewiesen wird. Er weiß also nicht, welchen Typ er für eins und zwei verwenden soll Typen, die im Operator?: verwendet werden, stimmen nicht überein.

Das einzige Problem ist, die Konvertierung explizit zu machen:

 Func action = which ? new Func(One) : new Func(Two); 

Jons Lösung funktioniert

 var action = which ? (Func)One : Two; 

Eine andere Alternative besteht darin, einen neuen anonymen Delegierten selbst zu erstellen. Das ist semantisch klein, aber ich denke, das kann auch nützlich sein.

 Func action = x => which ? One(x) : Two(x); 

Ich finde diese Lil ‘eleganter, wenn auch nicht so kurz ..