介紹LINQ之前先介紹一下枚舉器
Iterator:枚舉器
如果你正在創建一個表現和行為都類似於集合的類,允許類的用戶使用foreach語句對集合中的成員進行枚舉將會是很方便的。
我們將以創建一個簡單化的List Box作為開始,它將包含一個8字符串的數組和一個整型,這個整型用於記錄數組中已經添加了多少字符串。
構造函數將對數組進行初始化並使用傳遞進來的參數填充它。
/// <summary> /// Iterator:枚舉器 /// 測試枚舉器,繼承IEnumerable,實現IEnumerator<T> GetEnumerator() /// </summary> /// <typeparam name="T"></typeparam> public class ListBox<T> : IEnumerable<T> { public List<T> Strings = new List<T>(); public ListBox(params T[] initialStrings) { foreach (T s in initialStrings) { Strings.Add(s); } } IEnumerator<T> IEnumerable<T>.GetEnumerator()//這個方法和下面的方法都必須實現 { foreach (T s in Strings) { yield return s; } } //GetEnumerator方法使用了新的 yield 語句。yield語句返回一個表達式。yield語句僅在迭代塊中出現, //並且返回foreach語句所期望的值。那也就是,對GetEnumerator的每次調用都//將會產生集合中的下一個字符串;所有的狀態管理已經都為你做好了! IEnumerator IEnumerable.GetEnumerator()//這個方法和上面的方法都必須實現 { throw new NotImplementedException(); } }
語言集成查詢 (LINQ) 是一組技術的名稱,這些技術建立在將查詢功能直接集成到 C# 語言(以及 Visual Basic
和可能的任何其他 .NET 語言)的基礎上。 借助於 LINQ,查詢現在已是高級語言構造,就如同類、方法、事件等等。
對於編寫查詢的開發人員來說,LINQ 最明顯的“語言集成”部分是查詢表達式。
查詢表達式是使用 C# 3.0 中引入的聲明性查詢語法編寫的。
通過使用查詢語法,您甚至可以使用最少的代碼對數據源執行復雜的篩選、排序和分組操作。
您使用相同的基本查詢表達式模式來查詢和轉換 SQL 數據庫、ADO.NET 數據集、XML 文檔和流以及 .NET 集合中的數據。
LINQ的基本格式如下所示: var <變量> = from <項目> in <數據源> where <表達式> orderby <表達式>
group分組子句 語句格式:var str = from p in PersonList group p by p.age group子句將數據源中的數據進行分組,在遍歷數據元素時,並不像前面的章節那樣直接對元素進行遍歷,因為group子句返回的是元素類型為IGrouping<TKey,TElement>的對象序列,必須在循環中嵌套一個對象的循環才能夠查詢相應的數據元素。 在使用group子句時,LINQ查詢子句的末尾並沒有select子句,因為group子句會返回一個對象序列,通過循環遍歷才能夠在對象序列中尋找到相應的對象的元素,如果使用group子句進行分組操作,可以不使用select子句。 orderby排序子句 語句格式:var str = from p in PersonList orderby p.age select p; orderby子句中使用descending關鍵字進行倒序排列 示例代碼如下: var str = from p in PersonList orderby p.age descending select p; orderby子句同樣能夠進行多個條件排序,只需要將這些條件用“,”號分割即可 示例代碼如下: var str = from p in PersonList orderby p.age descending,p.name select p; join連接子句 在LINQ中同樣也可以使用join子句對有關系的數據源或數據對象進行查詢,但首先這兩個數據源必須要有一定的聯系 var str = from p in PersonList join car in CarList on p.cid equals car.cid select p;
下面的這個是LInq中常用的類
Enumerable 類 (System.Linq)
public class LinqClass { public static void Test1() { int[] scores = { 90, 92, 42, 46, 37, 32, 74, 5, 16, 32 }; IEnumerable<int> scoreQuery = from score in scores //必須 where score > 40 //可選條件 orderby score descending //可選條件 select score; //必須 foreach (int score in scoreQuery) { Console.WriteLine(score); } int hightestScore = scores.Max(); //group 分組 var queryGroups = from score in scores group score by score; //into 存儲查詢的內容 //// percentileQuery is an IEnumerable<IGrouping<int, Country>> var percentileQuery = from score in scores group score by score into scorequery where scorequery.Key > 10 select scorequery; //在 from 開始子句以及 select 或 group 結束子句之間, //所有其他子句(where、join、orderby、from、let)都是可選的。 //任何可選子句都可以在查詢正文中使用零次或多次。 //let 子句 //使用 let 子句可以將表達式(如方法調用)的結果存儲到新的范圍變量中。 string[] names = { "a n", "b c", "c n", "d m" }; IEnumerable<string> queryFirstNames = from name in names let firstName = name.Split(new char[] { ' ' })[0] select firstName; //對一個序列應用累加器函數。 //Aggregate<TSource>(IEnumerable<TSource>, Func<TSource, TSource, TSource>) string sentence = "the quick brown fox jumps over the lazy dog"; string[] words = sentence.Split(' '); string reversed = words.Aggregate((wording, next) => wording + " " + next); Console.WriteLine(reversed); //確定是否對序列中的所有元素都滿足條件。 //All<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>) //確定序列是否包含任何元素。 //Any<TSource>(IEnumerable<TSource>) List<int> numbers = new List<int> { 1, 2 }; bool hasElements = numbers.Any(); Console.WriteLine("The list {0} empty.", hasElements ? "is not" : "is"); // 返回輸入類型化為 IEnumerable<T>。 // AsEnumerable<TSource>(IEnumerable<TSource>) //將強制轉換的元素 IEnumerable 為指定的類型。符合規則熱任意類型,與上面的區別。 //Cast<TResult>(IEnumerable) //計算序列的平均值 Double 值。 //Average(IEnumerable<Double>) //連接兩個序列。 //Concat<TSource>(IEnumerable<TSource>, IEnumerable<TSource>) //確定序列是否包含指定的元素使用的默認相等比較器。 //Contains<TSource>(IEnumerable<TSource>, TSource) //返回序列中的元素數。 //Count<TSource>(IEnumerable<TSource>) //返回單一實例集合中指定的序列或類型參數的默認值的元素,如果序列為空。 //DefaultIfEmpty<TSource>(IEnumerable<TSource>) //通過使用的默認相等比較器對值進行比較從序列返回非重復元素。 //Distinct<TSource>(IEnumerable<TSource>) //返回序列中的指定索引處的元素。 //ElementAt<TSource>(IEnumerable<TSource>, Int32) //通過使用默認的相等比較器對值進行比較,生成兩個序列的差集。 //Except<TSource>(IEnumerable<TSource>, IEnumerable<TSource>) double[] numbers1 = { 2.0, 2.1, 2.2, 2.3, 2.4, 2.5 }; double[] numbers2 = { 2.2 }; IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2); foreach (double number in onlyInFirstSet) Console.WriteLine(number); //返回一個序列的第一個元素。 //First<TSource>(IEnumerable<TSource>) //返回序列中滿足指定條件的第一個元素。 //FirstOrDefault<TSource>(IEnumerable<TSource>) //根據指定的鍵選擇器函數對序列的元素進行分組。 //GroupBy<TSource, TKey>(IEnumerable<TSource>, Func<TSource, TKey>) // 通過使用默認的相等比較器對值進行比較,生成兩個序列的交集。 //Intersect<TSource>(IEnumerable<TSource>, IEnumerable<TSource>) int[] id1 = { 44, 26, 92, 30, 71, 38 }; int[] id2 = { 39, 59, 83, 47, 26, 4, 30 }; IEnumerable<int> both = id1.Intersect(id2); foreach (int id in both) Console.WriteLine(id); //通過使用默認的相等比較器生成的兩個序列的並集。 //Union<TSource>(IEnumerable<TSource>, IEnumerable<TSource>) //返回一個序列的最后一個元素。 //Last<TSource>(IEnumerable<TSource>) // 從序列的開頭返回指定的數量的連續元素。 // Take<TSource>(IEnumerable<TSource>, Int32) // 返回序列中的最大值 Decimal 值。 //Max(IEnumerable<Decimal>) //返回序列的唯一元素;如果該序列並非恰好包含一個元素,則會引發異常。 //Single<TSource>(IEnumerable<TSource>) //ToDictionary<TSource, TKey>(IEnumerable<TSource>, Func<TSource, TKey>) //Where<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>) // 一個序列的每個元素投影 IEnumerable<T> 並將合並為一個序列將結果序列。 //SelectMany<TSource, TResult>(IEnumerable<TSource>, Func<TSource, IEnumerable<TResult>>) } }
其他的基礎功能
5. C#中泛型的解釋(object,list,var,dynamic的區別)
6. C#中委托
7. C#和.NET版本對比