議程
1.LINQ和LINQ表達式
2.Lambda表達式
兩個接口
IEnumerable <T> 泛型接口
公開枚舉數,該枚舉數支援在指定類型的集合上進行簡單疊代。
public class MyCollections<T> : IEnumerable<T>
{
T[] values = new T[100];
public IEnumerator<T> GetEnumerator()
for (int i = 0; i < 100; i++)
yield return values[i];
}
IEnumerator IEnumerable.GetEnumerator()
return GetEnumerator();
class Class2
static void Main()
MyCollections&lt;int> Mycol = new MyCollections<int>();
foreach (int i in Mycol)
Console.WriteLine(i);
Iqueryable<T>
提供對資料類型已知的特定資料源的查詢進行計算的功能。
此接口繼承 IEnumerable<T>接口,是以,如果它表示一個查詢,則可以枚舉該查詢的結果。枚舉強制執行與 Iqueryable<T>對象關聯的表達式目錄樹。
LINQ基本概念
LINQ:語言內建查詢(Language Integrated Query),是一系列标準查詢操作符的集合,這些操作符幾乎對每一種資料源的導航,過濾和執行都是提供了底層的基本查詢架構。
LINQ可查的資料源包括關系資料,XML,DataSet或記憶體中的資料。
LINQ出現的背景:大多數開發人員對OO的熟悉,最好提把對資料的操作轉化成對對象的操作。
LINQ恰好将标準查詢功能直接整合到了供開發人員選擇的基于.NET的程式設計語言中。
LINQ支術的重點是查詢表達式,因為它描述了對資料源的具體操作。
LINQ查詢表達式基本概念
1.查詢表達式可用于查詢和轉換來自任意支援 LINQ 的資料源中的資料。例如,單個查詢可以從 SQL 資料庫檢索資料,并生成 XML 流作為輸出。
2.查詢表達式容易掌握,因為它們使用許多常見的 C# 語言構造。
3.查詢表達式中的變量都是強類型的,但許多情況下您不需要顯式提供類型,因為編譯器可以推斷類型。
4.在您循環通路 foreach 語句中的查詢變量之前,不會執行查詢。
5.在編譯時,根據 C# 規範中設定的規則将查詢表達式轉換為“标準查詢運算符”方法調用。任何可以使用查詢文法表示的查詢也可以使用方法文法表示。但是,在大多數情況下,查詢文法更易讀和簡潔。
6.作為編寫 LINQ 查詢的一項規則,建議盡量使用查詢文法,隻在必需的情況下才使用方法文法。這兩種不同形式在語義或性能上沒有差別。查詢表達式通常比用方法文法編寫的等效表達式更易讀。
7.一些查詢操作,如 Count 或 Max,沒有等效的查詢表達式子句,是以必須表示為方法調用。方法文法可以通過多種方式與查詢文法組合。
8.查詢表達式可以編譯為表達式目錄樹或委托,具體取決于查詢所應用到的類型。IEnumerable<(Of &lt;(T>)&gt;) 查詢編譯為委托。IQueryable 和 IQueryable<(Of &lt;(T>)&gt;) 查詢編譯為表達式目錄樹。
LINQ查詢表達式
查詢操作包含三部分:
擷取資料源
建立查詢
執行查詢
Demo:
//擷取資料源
string[] Devices= {"電視" ,"電冰箱","洗衣機","電話","微波爐"};
//建立查詢
var SelectDevices = from device in Devices
where device.StartsWith("電")
select device;
//執行查詢
foreach (string dev in SelectDevices)
Console.WriteLine("帶電的裝置:{0}",dev);
匿名方法
在 2.0 之前的 C# 版本中,聲明委托的唯一方法是使用命名方法。C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表達式取代了匿名方法,作為編寫内聯代碼的首選方式。不過,本主題中有關匿名方法的資訊同樣也适用于 Lambda 表達式。有一種情況下,匿名方法提供了 Lambda 表達式中所沒有的功能。匿名方法使您能夠省略參數清單,這意味着可以将匿名方法轉換為帶有各種簽名的委托。這對于 Lambda 表達式來說是不可能的。
button1.Click += delegate(System.Object o, System.EventArgs e)//匿名方法參數
{//匿名方法方法體
MessageBox.Show("Click!");
};
Lambda表達式
“Lambda 表達式”是一個匿名函數,它可以包含表達式和語句,并且可用于建立委托或表達式目錄樹類型。
所有 Lambda 表達式都使用 Lambda 運算符 =&gt;,該運算符讀為“goes to”。該 Lambda 運算符的左邊是輸入參數(如果有),右邊包含表達式或語句塊。Lambda 表達式 x =&gt; x * x 讀作“x goes to x times x”。可以将此表達式配置設定給委托類型
del myDelegate = x =&gt; x * x; int j = myDelegate(5); //j = 25 Console.WriteLine(j); delegate int del(int i);
隻有在 Lambda 有一個輸入參數時,括号才是可選的;否則括号是必需的。兩個或更多輸入參數由括在括号中的逗号分隔:
(x, y) =&gt; x == y
有時,編譯器難于或無法推斷輸入類型。如果出現這種情況,您可以按以下示例 中所示方式顯式指定類型:
(int x, string s) =&gt; s.Length &gt; x uLambda 語句與 Lambda 表達式類似,隻是語句括在大括号中: delegate void TestDelegate(string s); … TestDelegate myDel = n =&gt; { string s = n + " " + "World"; Console.WriteLine(s); }; myDel("Hello");
在編寫 Lambda 時,通常不必為輸入參數指定類型,因為編譯器可以基于 Lambda 主體、基礎委托類型以及 C# 3.0 語言規範中描述的其他因素推斷類型。對于大多數标準查詢運算符,第一個輸入是源序列中的元素的類型。是以,如果要查詢 IEnumerable<Customer>,則輸入變量将被推斷為 Customer類型,這意味着您可以通路其方法和屬性:
customers.Where(c =&gt; c.City == "London");
Lambda 的一般規則如下:
Lambda 包含的參數數量必須與委托類型包含的參數數量相同。
Lambda 中的每個輸入參數必須都能夠隐式轉換為其對應的委托參數。
Lambda 的傳回值(如果有)必須能夠隐式轉換為委托的傳回類型。
Lambda 可以引用“外部變量”,這些變量位于在其中定義 Lambda 的封閉方法或類型的範圍内。将會存儲通過這種方法捕獲的變量以供在 Lambda 表達式中使用,即使變量将以其他方式超出範圍或被作為垃圾回收。必須明确地配置設定外部變量,然後才能在 Lambda 表達式中使用該變量。
捕獲的變量将不會被作為垃圾回收,直至引用變量的委托超出範圍為止。
在外部方法中看不到 Lambda 表達式内引入的變量。
Lambda 表達式無法從封閉方法中直接捕獲 ref 或 out 參數。
Lambda 表達式中的傳回語句不會導緻封閉方法傳回。
Lambda 表達式不能包含其目标位于所包含匿名函數主體外部或内部的 goto 語句、break 語句或 continue 語句。
查詢文法和方法文法
查詢文法
方法文法
var SelectDevices =Devices .Where ( device =&gt; device.StartsWith("電"))
<a href="http://axzxs.blog.51cto.com/attachment/200908/24/730810_12510772212jeO.png"></a>
本文轉自桂素偉51CTO部落格,原文連結: http://blog.51cto.com/axzxs/195098,如需轉載請自行聯系原作者