2008-09-19 31 views
11

隨着lambda表達式(內聯代碼)等新功能的出現,這是否意味着我們不必再使用委託或匿名方法?在我看到的幾乎所有樣本中,都是使用新語法重寫的。有沒有一種情況下,委託語法優於匿名方法的lambda表達式?

任何我們仍然必須使用委託和lambda表達式的地方都不行?

+0

另請參見[差異之間的差異 - 匿名方法和lambda表達式](http://stackoverflow.com/questions/208381/whats-the-difference-between-anonymous-methods-c -2-0和lambda表達式)的一般差異。 – nawfal 2014-07-03 11:30:07

回答

8

lambda是匿名委託的快捷方式,但您將始終使用委託。委託指定方法簽名。你可以這樣做:

delegate(int i) { Console.WriteLine(i.ToString()) } 

可以

f => Console.WriteLine(f.ToString()) 
3

Lambda表達式替換隻是「語法糖」,編譯器將產生相應的代表爲您服務。你可以使用Lutz Roeder的Reflector來調查。

+1

實際上,lambda表達式比語法糖多一點,因爲它們可以編譯到表達式樹中並進行操作。 – 2008-09-19 23:24:35

+0

反射器現在由redgate擁有[http://www.red-gate.com/products/reflector/] – cori 2008-09-20 02:40:47

3

的Lamda的是代表只是語法糖,他們不只是爲inline,可以做到以下幾點:

s.Find(a => 
{ 
    if (a.StartsWith("H")) 
     return a.Equals("HI"); 
    else 
     return !a.Equals("FOO"); 
}); 

並定義事件時,或代表仍在使用,當你有很多的爭論,並希望實際上強烈鍵入正在調用的方法。

27

是的,有些地方直接使用匿名代理和lambda表達式不起作用。

如果一個方法需要一個無類型的Delegate,那麼編譯器不知道該如何解析匿名委託/ lambda表達式,並且會得到編譯器錯誤。

public static void Invoke(Delegate d) 
{ 
    d.DynamicInvoke(); 
} 

static void Main(string[] args) 
{ 
    // fails 
    Invoke(() => Console.WriteLine("Test")); 

    // works 
    Invoke(new Action(() => Console.WriteLine("Test"))); 

    Console.ReadKey(); 
} 

的代碼失敗的行會得到編譯器錯誤「無法轉換lambda表達式鍵入‘System.Delegate’,因爲它不是一個委託類型」。

+0

我認爲提問者詢問`delegate`關鍵字已過時,以支持更新的基於lambda的語法。她將「匿名方法和代表」組合在一起。 – nawfal 2013-12-20 10:02:44

3

委託在C#中有兩個含義。

關鍵字delegate可用於定義函數簽名類型。這通常用於確定高階函數的簽名,即將其他函數作爲參數的函數。委託的這種使用仍然相關。

關鍵字delegate也可用於定義內聯匿名函數。在函數只是單個表達式的情況下,lambda語法是一個更簡單的選擇。

7

Lambda表達式不是(也不是意味着)將取代(隱藏)代表的銀色子彈。它與當地的小東西是偉大的,如:

List<string> names = GetNames(); 
names.ForEach(Console.WriteLine); 
  1. 它使代碼更易讀這樣簡單的理解。
  2. 這使得代碼更短對我們這樣工作少;)

在另一方面,它是非常簡單的濫用它們。長和/或複雜的lambda表達式都趨向於:

  1. 很難理解新開發
  2. 面向
  3. 更難讀

少對象,因此「它意味着我們不'不必再使用委託或匿名方法了嗎?「否 - 使用Lambda表達式來贏得時間/可讀性,否則請考慮使用委託。

+0

哇!我從來沒有想過這個!有沒有辦法做謂詞,即names.Where(!string.IsNullOrEmpty)); ?我試過了,它不適合我。 哎呀!如果我刪除!操作數它工作,爲什麼?我甚至試圖把它放在括號裏,但它不能完全調用它,有沒有辦法? 我們實際上正試圖將string.IsNullOrEmpty轉換爲string.IsNotNullOrEmpty ... – Shimmy 2009-07-23 04:53:56

2

其中一個沒有那麼大較舊的delegate語法的優點是如果您不在方法體中使用它,則不需要指定參數。從msdn

有一種情況,其中一個匿名方法提供的功能 在lambda表達式未找到。匿名方法使您可以省略參數列表 。這意味着匿名方法可以將 轉換爲具有各種簽名的委託。對於lambda表達式,這不是 。

例如,你可以這樣做:

Action<int> a = delegate { }; //takes 1 argument, but not specified on the RHS 

雖然失敗:

button.onClicked += delegate { Console.WriteLine("clicked"); }; 

Action<int> a = => { }; //omitted parameter, doesnt compile. 

這種技術撰寫事件處理程序時,像大多來得心應手這不是的優勢。最好採用總是imho的新語法。

相關問題