2009-02-19 4 views
29

Тип условного выражения не может быть определена, так как не существует неявное преобразование между «лямбда-выражения» и «лямбда-выражения»C#: неявное преобразование между «лямбда-выражением» и «лямбда-выражением»?

Скажем whaat? Может ли кто-нибудь объяснить мне эту ошибку компиляции? Это код, который производит его:

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

Это не:

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

И ни это сделать:

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

ответ

41

Тип условного выражения должен быть выведен как целые и лямбда-выражения всегда должны быть преобразованы в конкретный тип делегата или дерева выражений.

В последних двух примерах компилятор знает, к чему он стремится преобразовать лямбда-выражение. В первом примере он сначала пытается выработать тип всего условного выражения.

Бросок в одной из ветвей будет достаточно, хотя:

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

затруднительное Sergio (теперь удален, но включены ниже) будет работать если вы были счастливы оценить someBool в то время функция является вызванный:

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

В зависимости от сроков существует множество способов устранения приведенного вами примера, например

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

Я предполагаю, что ваш реальный код более сложный.

Это позор в некотором роде, что вывод типа C# не может быть более мощным, но это уже довольно сложно.

+2

За исключением необходимости обернуть первую ветвь в круглых скобках, это сработало да ... Надеюсь, они может сделать вывод типа C# еще лучше в будущем. Хотя, это довольно хорошо уже =) – Svish

+0

Хорошие варианты, на самом деле не думал ни о одном из них. Но это станет более ясным: – Svish

+0

, вы думаете, это то, что они когда-либо улучшат? Эта проблема (и другие подобные ей - как неспособность использовать ** var ** с лямбдами) действительно кажутся позором. –

Смежные вопросы