2011-02-22 73 views
7

在使用LINQ時是必須使用lambda表達式還是lambda表達式是可選的?Lambda表達式語法

在lambda表達式中,總是使用符號=>。這是什麼意思?

customers.Where(c => c.City == "London"); 

這裏c =>使用,但爲什麼呢? 用什麼樣的意思c =>。請詳細討論,因爲我不知道lambda。

回答

7

Lambda表達式

c => c.City == "London" 

是簡寫形式,像

bool IsCustomerInLondon(Customer c) 
{ 
    return (c.City == "London"); 
} 

這只是一個寫一個簡單的函數返回一個值的非常簡潔的方式。它被稱爲「匿名函數」,因爲它從來沒有被分配一個名稱或一個正式的定義(參數類型和返回類型是從上下文中推斷出來的)。

(其實,這不是只是速記; lambda表達式都涉及到一些其他的結構稱爲closures,這是非常冷靜和強大的工具。)

+0

請注意,lambda表達式也可以轉換爲表達式樹。 – 2011-02-22 18:52:26

11

不,你不要使用lambda表達式。例如,您Where例子可以寫成:

private static bool IsLondon(Customer customer) 
{ 
    return customer.City == "London"; 
} 

... 

var londoners = customers.Where(IsLondon); 

這是假設LINQ到對象,當然。對於LINQ to SQL等,你需要建立一個表達式樹。

至於爲什麼「=>」總是用在lambda表達式中,那只是因爲這就是操作符編寫的方式 - 就像問爲什麼用「+」來加法。

的「C => ...」被有效地賦予lambda表達式一個參數稱爲c ...在這種情況下一般類型推理lambda表達式提供類型的c。正文提供了一個要執行的動作或一些計算來返回基於c的值。

對lambda表達式的全面描述超出了本答案的範圍。然而,作爲my book的一個明顯的插件,它們在C#深度的第9章中有詳細介紹。

+0

哈,你在我之前編輯過:p – TimothyP 2011-02-22 18:42:05

1

Lambda和LINQ是完全分離。您可以使用一個不使用其他(有依賴於lambda表達式LINQ的部分,但我們要保持它的簡單:-))

lambda表達式是匿名 功能,可以包含表達式 和陳述,並可用於 創建代表或表達式樹 類型。

這是來自MSDN。 (http://msdn.microsoft.com/en-us/library/bb397687。aspx)

爲了縮短它(更復雜),可以使用lambda表達式來創建本地函數。你在=>之前放置了什麼(在你的例子中,c)將是函數的參數。返回類型是C#編譯器「發現」的。

c => c.City == "London"幾乎相當於:

delegate (TheObjectTypeOfC c) { 
    return c.City == London 
}; 

(不同的是,一些lambda表達式的代表也表達,但請忽略這一點,你就不必了一段時間)

如果/當編譯器無法推斷參數的類型時,可以強制它們:(MyObject p) => p.SomeProperty != null。這裏你告訴編譯器p是一個參數。

而在這裏我給你什麼是所謂的「表達lambda表達式」,你甚至可以做「lambda表達式」:

p => { 
    for (int i = 0; i < 10; i++) { 
     if (p.SomeProperty == 0) { 
      return true; 
     } 
    } 

    return false; 
} 

(我不會告訴你什麼是之間的「幕後」的差異如果你想知道它們,請閱讀我之前指出的msdn頁面)

+0

它們不是完全獨立的,因爲查詢表達式(它是LINQ的一部分)的翻譯依賴於lambda表達式。然而,它*很公平地說,你可以在不使用lambda表達式的情況下使用LINQ庫。 – 2011-02-22 18:45:19

1

Jon已經回答了, 但我想補充一點。

在你給的例子,想象的LINQ遍歷所有的客戶, c是簡單地在枚舉的每個項目的引用:

var result = new List<Customer>(); 
foreach(var c in customers) 
{ 
    if (c.City == "London") 
     result.Add(c); 
} 
return result; 

這就像任何其他的變量,它沒有成爲一個單一的名字, 但它只是一種約定。

1

您不需要在Lİnq上將lambda表達式用於sql或Entities;這裏是你的代碼的另一種方式;

你代碼:

customers.Where(c => c.City == "London"); 

的其他方式;

var query = from cs in customers 
       where cs.City == "London" 
       select cs; 

這是另一種方式。它是由你決定。

4

將lambda認爲是函數的匿名。 我會嘗試用下面的代碼來解釋它。

public bool IsLondon(Customer customer) 
{ 
    return customer.City == "London"; 
} 

現在我們剝離下來函數名和擺脫牙套:

public bool Customer customer  
    return customer.City == "London"; 

我們不需要返回類型,因爲編譯器能夠從表達推斷類型:

customer.City == "London"; 

以相同的方式編譯器知道輸入類型,所以我們不需要指定它。

所以基本上,我們留下的是

customer 
    return customer.City == "London"; 

而在C#lambda語法基本上是:

(parameter list) => "expression" 

你也可以寫「多線」的表達,但你必須要用花括號圍繞你的代碼。你也需要像往常一樣使用「return」語句。

1

不,根本沒有必要。

我們有兩種編寫LINQ查詢的方法。

一個是查詢方法,另一個是構建方法。你只需要在構建器方法中使用lambda表達式。 例如,如果我們要找出所有從一些學生對象中具有多個標記比70 這些學生,但我們可以做LINQ這件事情有以下語法

var data = from p in stdList 
    where p.marks > 70 
    select p; 

或 VAR數據= stdList.Where (p => p.marks> 70);

後面的方法是builder方法,在Where函數中,我們傳遞了lambda表達式。

Lambda表達式只是處理事情的捷徑,您可以始終使用LINQ查詢,但如果您想避免僅應用簡單條件的整個查詢語法,則可以在lambda表達式中使用LINQ構建器方法(要求使用lambda表達式)表達式,你總是定義一些別名,然後執行你的操作。

就=>運算符而言,它和賦值運算符一樣工作。 例如:

(p) => p.Gender == 「F」 
It means 「All persons p, such that person’s Gender is F」 

在一些文獻中這被稱爲「謂詞」。另一種文學術語是「投影」

(p) => p.Gender ? 「F」 : 「Female」 
「Each person p becomes string 「Female」 if Gender is 「F」」 

這是投影,它使用三元運算符。 雖然我用非常基本的例子解釋,但我希望這可以幫助你。 。 。 :)