2015-01-06 13 views
24

Tôi đọc mà C lambdas # có thể được imlicitly chuyển thành hành động hoặc Func, nhưng lambda không thể được thực hiện trực tiếp Define a lambda function and execute it immediately Ví dụ:Loại lambda thực sự trong C# là gì?

int n = (()=>5)(); //doesn't work 
int n = ((Func<int>)(()=>5))(); //works 

Vì vậy, là những gì các loại thực tế của lambda và tại sao nó không thể được gọi trực tiếp? Có phải vì hệ thống kiểu C# là "yếu hơn" so với Haskell hay Scala?

+2

Loại ẩn danh ??. –

+2

Câu trả lời trong câu hỏi được liên kết là hợp lệ cho câu hỏi của bạn. Trình biên dịch C# cần phải biết ngữ cảnh, đó là một trong hai nhiệm vụ hoặc đúc. Trong mẫu đầu tiên bạn không phải – Leri

+0

Hệ thống kiểu không liên quan đến điều này. 'Dim n = Function() 5' hoạt động tốt trong VB.NET, và nó tương tự trong F #, và chúng có cùng hệ thống kiểu cơ bản. Đây chỉ là vấn đề với C#. –

Trả lời

26

Biểu thức lambda không có loại. Nó không thể, bởi vì bất kỳ loại nào trong thế giới .NET mà nó có thể có, cũng sẽ khó mã hóa kiểu tham số và kết quả của lambda. Bây giờ hãy xem xét:

x => x + 1 

Loại nào có thể x có? Loại kết quả sẽ là gì? Không có bất kỳ câu trả lời duy nhất nào, và biểu thức lambda thực sự có thể được chuyển đổi thành Func<int, int>, Func<double, double> và nhiều loại đại biểu khác với các tham số khác nhau. Đưa ra một biểu thức lambda một loại sẽ không cho phép các biểu thức như vậy. C# đã muốn cho phép các biểu thức như vậy, do đó, được thiết kế để không đưa ra các biểu thức như vậy.

+1

cũng giải thích, nếu một ví dụ mã được đưa ra, tôi am instersted –

+2

Tôi không chắc chắn những gì sắp xếp của ví dụ mã bạn có trong tâm trí, tất cả tôi có thể nghĩ rằng để thêm là ví dụ về các loại đại biểu biểu thức có thể được chuyển đổi, mà tôi đã bao gồm trong câu trả lời. – hvd

+0

Điều đó có ý nghĩa. Tôi vừa thử nghiệm điều này trong F # và Haskell. Trong F # chỉ hoạt động với "int" - lý do là F # không sử dụng chuyển đổi ngầm. Trong trường hợp của trình biên dịch C# - thực sự không thể "biết" loại, vì vậy bạn là đúng. –

9

Điều này là do () => 5 có thể tương thích với nhiều loại đại biểu khác nhau (ví dụ: bạn có thể có tùy chỉnh delegate không mất gì và trả lại int). Và để tạo ra một delegate, trình biên dịch phải biết chính xác loại. Nó không thể chỉ chọn một loại ngẫu nhiên phù hợp với nhu cầu của bạn. Vì vậy, đó là lý do tại sao trừ khi bạn đưa nó vào một loại đại biểu thực tế, bạn không thể Invoke nó.

Trong trường hợp như thế, nơi một phương pháp dự đoán một delegate, chuyển đổi được thực hiện ngầm bởi trình biên dịch:

void Foo(Func<int> func) { } 

Foo(() => 5); 

Và nó cũng rất quan trọng để biết rằng delegates thực sự các lớp học đằng sau hậu trường. Và mỗi khi bạn tạo một cá thể delegate, trình biên dịch sẽ tạo một cá thể của số đó class. Vì vậy, một trong hai cách bạn phải chỉ định một loại để trình biên dịch sẽ biết được loại sử dụng.

+0

khi chúng ta đặt ''() => '' vào '' Select() '' hoặc '' Where() '' nghĩa là gì? xin vui lòng giải thích –

+0

@EhsanSajjad Tôi chỉ cần thêm rằng để trả lời :) –

+0

tôi cần làm rõ cho bản thân mình vì tôi không rõ ràng .. :) –

Các vấn đề liên quan