2012-04-17 31 views
22

Có cách nào để thực hiện một biểu thức lambda ngay sau khi định nghĩa của nó?Thực hiện biểu thức lambda ngay lập tức sau khi định nghĩa của nó?

Nói cách khác (không hợp lệ C# code):

(() => { Console.WriteLine("Hello World"); }).Invoke(); 
+0

Chờ ... cái gì? Tại sao nó là một biểu thức lambda? – scottheckel

+4

Lý do mã của bạn không hợp lệ là vì bạn chưa nói cho trình biên dịch biết bạn có muốn 'Tác vụ' hoặc' Biểu thức 'hay không. Nếu bạn đưa biểu thức lambda đó vào 'Action', bạn sẽ có thể gọi' Invoke' trên nó hoặc sử dụng cú pháp gọi phương thức '()' để gọi nó. – phoog

+4

Trí tưởng tượng của tôi có thể thất bại trong tôi, có cần phải thực hiện điều này không? –

Trả lời

32

chắc.

new Action(() => { Console.WriteLine("Hello World"); })(); 

Điều đó cần thực hiện thủ thuật.

3

Bạn sẽ có thể làm điều này:

Action runMe =() => { Console.WriteLine("Hello World"); }; 
runMe(); 
+0

Chính xác. Trình biên dịch sẽ giải thích cú pháp lambda như là viết tắt của một đại biểu. Chỉ khi bạn gán một loại 'Expression ' thì nó sẽ tạo ra cây biểu thức. – Tejs

+3

Điều này sẽ không biên dịch vì trình biên dịch không thể tìm ra liệu bạn có muốn 'Action' hoặc' Expression 'hay không. – phoog

+1

@phoog là chính xác. Điều này sẽ không biên dịch. "Không thể gán biểu thức lambda cho biến cục bộ được nhập ngầm." –

12

Một "tùy chọn", mà chỉ là hai câu trả lời khác trong một vỏ bọc hơi khác nhau:

((Action)(() => { Console.WriteLine("Hello World"); }))(); 

Lý do, như trực tiếp lấy từ nhận xét của phoog:

... bạn chưa thông báo cho trình biên dịch Bạn muốn có một số Action hoặc Expression<Action>. Nếu bạn truyền biểu thức lambda đó thành Action, bạn sẽ có thể gọi Invoke trên đó hoặc sử dụng cú pháp gọi phương thức() để gọi nó.

Nó chắc chắn bị xấu xí mặc dù, và tôi không biết một nơi mà hình thức này là bao giờ hữu ích, vì nó không thể được sử dụng cho đệ quy mà không có tên ...

+0

Bạn hoàn toàn có thể làm đệ quy với điều này, sử dụng bộ kết hợp Y:' đại biểu công khai T đệ quy (đệ quy f, T n); static void Main (string [] args) {System.Console. WriteLine ("Factorial 5 = {0}", mới đệ quy ((f, n) => f (f, n)) (đệ quy mới ((f, n) => (n == 0)? 1: n * f (f, n - 1)), 5));} '. Nó là một hack từ thế giới thuần túy chức năng, mà về cơ bản tuyên bố một chức năng' f' lấy chính nó như là một tham số, và đệ quy gọi chính nó bằng cách đi qua 'f Để bắt đầu đệ quy, hàm này được truyền cho hàm khác gọi 'f' với' f' và giá trị ban đầu của tham số. –

1

Dưới đây là một ví dụ về cách này có thể được sử dụng. Bạn muốn khởi tạo một hàm tạo với kết quả của một vài dòng mã không thể được viết dưới dạng hàm bởi vì đó là cách API của bên thứ ba được cấu trúc.

Nó chỉ là mã keo để ngăn chặn viết một hàm độc lập mà không bao giờ được gọi là bất cứ nơi nào khác. Tôi đang sử dụng Func thay vì Action, nhưng câu trả lời giống với user166390.

 // imagine several dozens of lines that look like this 
     // where the result is the return value of a function call 
     fields.Add(new ProbeField(){ 
      Command = "A", 
      Field = "Average", 
      Value = be.GetAverage() 
     }); 

     // now you need something that can't be expressed as function call 
     // so you wrap it in a lambda and immediately call it. 
     fields.Add(new ProbeField(){ 
      Command = "C", 
      Field = "Cal Coeff", 
      Value = ((Func<string>)(() => { 
       CalCoef coef; 
       Param param; 
       be.GetCalibrationCoefficients(out coef, out param); 
       return coef.lowDet1.ToString(); 
      }))() 
     }); 
Các vấn đề liên quan