C#高級功能(二)LINQ 和Enumerable類

介紹LINQ以前先介紹一下枚舉器html

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>>)
        }
    }

 

其餘的基礎功能

1.  C#高級功能(四)擴展方法和索引ui

2. C#高級功能(三)Action、Func,Tuplespa

3. C#高級功能(二)LINQ 和Enumerable類code

4. C#高級功能(一)Lambda 表達式htm

5. C#中泛型的解釋(object,list,var,dynamic的區別)對象

6. C#中委託

7. C#和.NET版本對比

相關文章
相關標籤/搜索