2012-04-17 74 views
22

有沒有辦法在定義之後立即執行lambda表達式?在其定義後立即執行lambda表達式?

換言之(無效的C#代碼):

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

等等......什麼?爲什麼是lambda表達式? – scottheckel 2012-04-17 20:11:17

+4

你的代碼無效的原因是你沒有告訴編譯器你想要一個'Action'還是'Expression '。如果將該lambda表達式轉換爲「Action」,則可以調用它的「Invoke」或使用方法調用語法'()來調用它。 – phoog 2012-04-17 20:14:41

+4

我的想象力可能會讓我失望,是否真的需要這樣做? – 2012-04-17 20:17:03

回答

32

不確定。

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

這應該做的伎倆。

3

你應該能夠做到這一點:

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

正確。編譯器會將lambda語法解釋爲代表的簡寫。只有當你分配一個表達式時,它纔會構建表達式樹。 – Tejs 2012-04-17 20:14:37

+3

這將不會編譯,因爲編譯器無法確定您是需要「操作」還是「表達式」。 – phoog 2012-04-17 20:15:16

+1

@phoog是正確的。這不會編譯。 「不能將lambda表達式分配給隱式類型的局部變量。「 – 2012-04-17 20:16:13

12

另一個「選項」,這僅僅是在一個稍微不同的幌子其他兩個答案:

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

究其原因,直接取自phoog的評論

......你還沒有告訴編譯器,您需要ActionExpression<Action>。如果您將轉換爲表示lambda表達式爲Action,您可以調用它的Invoke或使用方法調用語法()來調用它。

毫無疑問它的醜陋,雖然,我不知道一個地方,這種形式是以往任何時候都非常有用,因爲它不能用於遞歸沒有名字的...

+0

你完全可以做這個遞歸,使用Y組合器:'公共代理T遞歸(遞歸 f,T n);靜態無效主要(字符串[] ARGS){系統。 WriteLine(「Factorial 5 = {0}」,new Recursive ((f,n)=> f(f,n)) n * f(f,n-1)),5));}'這是純粹功能性世界的破解,它基本上聲明瞭一個函數'f'作爲參數,並通過傳遞'f '爲了開始遞歸,這個函數被傳遞給另一個函數,它用'f'和參數的初始值調用'f'。 – 2013-06-28 15:32:07

1

這裏有一個如何這樣的一個例子可能會被使用。你想用幾行代碼的結果來初始化一個構造函數,這些代碼不能寫成函數,因爲這是第三方API的結構。

這只是膠水代碼,以防止編寫一個獨立的函數,這是從來沒有其他地方調用。我使用Func而不是Action,但答案與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(); 
      }))() 
     });