2009-02-19 15 views
29

Art des bedingten Ausdrucks kann nicht bestimmt werden, weil es keine implizite Konvertierung zwischen ‚Lambda-Ausdruck‘ ist und ‚Lambda-Ausdruck‘C#: Keine implizite Umwandlung zwischen 'Lambda-Ausdruck' und 'Lambda-Ausdruck'?

Say Whaat? Kann mir bitte jemand diesen Kompilierfehler erklären? Dies ist der Code, der es produziert:

protected override Func<System.IO.Stream> GetStream() 
    { 
     return someBool 
      ?() => EmbeddedResourceExtractor.GetFile("SomeFile1.ext") 
      :() => EmbeddedResourceExtractor.GetFile("SomeFile2.ext"); 
    } 

Dies gilt nicht:

protected override Func<System.IO.Stream> GetStream() 
    { 
     return() => EmbeddedResourceExtractor.GetFile("SomeFile1.ext"); 
    } 

Und auch dies tun:

protected override Func<System.IO.Stream> GetStream() 
    { 
     if(someBool) 
      return() => EmbeddedResourceExtractor.GetFile("SomeFile1.ext"); 
     return() => EmbeddedResourceExtractor.GetFile("SomeFile2.ext"); 
    } 
+3

http://stackoverflow.com/questions/263151/lambdas-and-the-ternary-operator-weird-issue – user17541

Antwort

41

Der Typ des bedingten Ausdrucks als Ausgang abgeleitet werden Ganzzahl- und Lambda-Ausdrücke müssen immer in einen bestimmten Delegat- oder Ausdrucksbaumtyp konvertiert werden.

In den letzten beiden Beispielen weiß der Compiler, wozu er den Lambda-Ausdruck konvertieren soll. Im ersten Beispiel wird zunächst versucht, den Typ des gesamten Bedingungsausdrucks zu ermitteln.

Ein Abguss in einem der Zweige würde jedoch ausreichen:

protected override Func<Stream> GetStream() 
{ 
    return someBool 
     ? (Func<Stream>) 
      (() => EmbeddedResourceExtractor.GetFile("SomeFile1.ext")) 
     :() => EmbeddedResourceExtractor.GetFile("SomeFile2.ext"); 
} 

Sergio fix (jetzt gelöscht, sondern auch weiter unten) wenn Sie die Zeit zu bewerten someBool an die Funktion funktioniert zufrieden waren genannt:

Je nach Timing gibt es alle Arten von verschiedenen Möglichkeiten zur Behebung des Beispiels, das Sie tatsächlich gegeben haben, z

protected override Func<Stream> GetStream() 
{ 
    string name = someBool ? "SomeFile1.ext" : "SomeFile2.ext"; 
    return() => EmbeddedResourceExtractor.GetFile(name); 
} 

Ich vermute, dass Ihr echter Code ist jedoch komplizierter.

Es ist eine Schande in mancher Hinsicht, dass C# 's Inferenz nicht leistungsfähiger sein kann - aber es ist schon ziemlich kompliziert.

+2

Mit der Ausnahme, den ersten Zweig in Klammern zu wickeln, das hat ja funktioniert ... Hoffe, sie kann die Typrückschlüsse der C# in Zukunft noch besser machen. Obwohl, es ist schon ziemlich schön =) – Svish

+0

Schöne Optionen, eigentlich hatte keiner von ihnen gedacht. Aber diese werden es klarer machen ja :) – Svish

+0

glauben Sie, das ist etwas, was sie jemals verbessern würden? Dieses Problem (und andere, die dem ähnlich sind - wie nicht in der Lage zu sein ** var ** mit lambdas zu verwenden) scheint tatsächlich eine Schande zu sein. –

Verwandte Themen