2009-02-19 71 views
29

Loại biểu thức điều kiện không xác định được vì không có chuyển đổi ngầm giữa 'biểu thức lambda' và 'biểu thức lambda'C#: Không có chuyển đổi ngầm giữa 'biểu thức lambda' và 'biểu thức lambda'?

Say whaat? Ai đó có thể vui lòng giải thích lỗi biên dịch này cho tôi? Đây là mã mà tạo ra nó:

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

này không:

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

Và không phải làm điều này:

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

Trả lời

41

Kiểu của biểu thức điều kiện phải được suy ra như một toàn bộ - và các biểu thức lambda luôn phải được chuyển đổi thành một loại cây đại biểu hoặc biểu thức cụ thể.

Trong hai ví dụ sau, trình biên dịch biết những gì nó đang cố chuyển đổi biểu thức lambda thành. Trong ví dụ đầu tiên, nó cố gắng làm việc ra loại biểu thức toàn bộ điều kiện trước tiên.

Một dàn diễn viên tại một trong những chi nhánh sẽ là đủ mặc dù:

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

sửa chữa Sergio của (nay là xóa, nhưng bên dưới) sẽ làm việc nếu bạn đã hạnh phúc để đánh giá someBool tại thời điểm chức năng là được gọi là:

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

Tùy thuộc vào thời gian, có nhiều cách khác nhau để sửa ví dụ bạn đã thực sự đưa ra, ví dụ

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

Tôi đoán mã thực sự của bạn phức tạp hơn.

Đó là một sự xấu hổ trong một số cách mà suy luận kiểu C# không thể mạnh hơn - nhưng nó đã khá phức tạp.

+2

Ngoại trừ việc phải quấn nhánh đầu tiên vào dấu ngoặc đơn, đã làm việc có ... Hy vọng họ có thể làm cho suy luận kiểu C# càng tốt hơn trong tương lai. Mặc dù, nó là khá tốt đẹp đã =) – Svish

+0

lựa chọn tốt đẹp, thực sự đã không nghĩ đến bất kỳ của họ. Nhưng những người sẽ làm cho nó rõ ràng hơn có :) – Svish

+0

bạn có cho rằng đây là một cái gì đó họ sẽ bao giờ cải thiện? Vấn đề này (và những người khác tương tự như nó - như không thể sử dụng ** var ** với lambdas) thực sự có vẻ là một sự xấu hổ. –