2017年8月13日 星期日

[C#] Feature introduced in C# 3.0

  • Feature introduced in C# 3.0
  • LINQ 查詢簡介 (C#) 
    • 所有的 LINQ 查詢作業都包含三個不同的動作: 
      • 取得資料來源 
      • 建立查詢 
        1. 查詢與執行查詢不同,查詢只建立變數並不會擷取任何資料
      • 執行查詢 Code
    • Code
class IntroToLINQ
{        
    static void Main()
    {
        // The Three Parts of a LINQ Query:
        //  1. Data source.
        int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };

        // 2. Query creation.
        // numQuery is an IEnumerable< int>
        var numQuery =
            from num in numbers
            where (num % 2) == 0
            select num;

        // 3. Query execution.
        foreach (int num in numQuery)
        {
            Console.Write("{0,1} ", num);
        }
    }
}
    • 下圖顯示完整的查詢作業 (Ref: LINQ_Query)
    • Linq 執行查詢分兩種:
      • 延後執行查詢
        1. 因執行"建立查詢"的作業將會延後至使用 foreach 陳述式時,每次取回相同條件查詢結果,稱為 "Deferred Execution"
        2. 因查詢變數本身將部會保留任何查詢結果,所以可以多次的查詢變數已取得最後的結果
        3. Code:如上列的範例
      • 強制立即執行
        1. 執行"彙總韓式"(Average, Sum, Count ... 等等)或者"查詢結果"(ToList, FirstOrDefault, First... 等等),取出回傳值
        2. 立即執行的方法,大多使用 Extension Method (擴充方法)
        3. Code 待補
  • Lambda 運算式 (C# 程式設計手冊)
    • Lambda 運算式是匿名函式,可用來建立委派運算式樹狀架構類型
    • 沒有名稱的函式
    • 執行運算並回傳單一值
    • 不需要撰寫冗長的匿名方法與委派
    • 基本語法
      • => 是 Lambda 運算子,意思為 “移至”
    • Code
      delegate int del(int i);  
      static void Main(string[] args)  
      {  
          del myDelegate = x => x * x;  
          int j = myDelegate(5); //j = 25  
      }  
    • 查詢語法中直接使用 Lambda 運算式,而是在方法呼叫中使用它們,因此查詢運算式可以包含方法呼叫
    • Code
      class SimpleLambda
      {
          static void Main()
          {
      
              // Data source.
              int[] scores = { 90, 71, 82, 93, 75, 82 };
      
              // The call to Count forces iteration of the source
              // 左邊的 n 是輸入變數,代表資料來源中的每一個物件
              int highScoreCount = scores.Where(n => n > 80).Count();
      
              Console.WriteLine("{0} scores are greater than 80", highScoreCount);
      
              // Outputs: 4 scores are greater than 80            
          }
      }
  • Extension 
Method 擴充方法 (C# 程式設計手冊)
    • 建議您應謹慎地實作擴充方法,而且只有在必要時才實作
    • 使用擴充方法來擴充無法變更其原始程式碼的類型時,會有類型實作的變更導致擴充方法中斷的風險
    • 定義
      • 靜態 (static) 類別中宣告靜態方法
      • 透過第一個參數前加上 this 關鍵字,指定要擴充的類別
    • 如下圖,C# 中已經實做許多擴充方法
    • Code
      
          class Program
          {
              static void Main(string[] args)
              {
                  string sName = "Lyndon";
                  sName.Print();
      
                  int nSum = 50;
                  Console.WriteLine(nSum.Add(100).Add(30));
              }
          }
      
          /// 
          /// 1. 靜態類別中
          /// 
          public static class Extensions
          {
              /// 
              /// 2. 宣告靜態方法 Print
              /// 3. 第一個參數前加上 this 關鍵字
              /// 4. 指定要擴充的類別 (string)
              /// 
              /// The aString.
              public static void Print(this string aString)
              {
                  Console.WriteLine(aString.ToUpper());
              }
      
              /// 
              /// Adds the specified aint.
              /// 
              /// The aint.
              /// The int add number.
              /// 
              public static int Add(this int aInt, int nAdd)
              {
                  return aInt + nAdd;
              }
          }
      
    • Result


  • Expression
 Tree 運算式樹狀架構 (C#)
    • 待續
  • Implicit Type(var) var (C# 參考)
    • 方法範圍宣告的變數具有隱含型別 var
    • 隱含型別區域變數是強型別 (Strongly Typed)
    • Code
      
      /// 
      /// implicitly typed  
      /// 
      var i = 10;
      var s = "Lyndon";
      /// 
      /// explicitly typed  
      /// 編譯器 (Compiler) 判斷型別
      /// 
      int i = 10;
      string s = "Lyndon";
    • Case1 (Linq IEnumerable<string>)
      
      // 查詢結果的型別可以明確陳述為 IEnumerable< string>,所以允許使用 var,但不需要這麼做
      // Example #1: var is optional because
      // the select clause specifies a string
      string[] words = { "apple", "strawberry", "grape", "peach", "banana" };
      var wordQuery = from word in words
                      where word[0] == 'g'
                      select word;
      
      // Because each element in the sequence is a string, 
      // not an anonymous type, var is optional here also.
      foreach (string s in wordQuery)
      {
          Console.WriteLine(s);
      }
    • Case2 (Linq anonymous type)
      
      // 名型別的集合,而且只有編譯器 (Compiler) 才可以存取該型別的名稱,所以必須使用 var
      // Example #2: var is required because
      // the select clause specifies an anonymous type
      var custQuery = from cust in customers
                      where cust.City == "Phoenix"
                      select new { cust.Name, cust.Phone };
      
      // foreach 反覆運算變數 item 也必須是隱含型別
      // var must be used because each item 
      // in the sequence is an anonymous type
      foreach (var item in custQuery)
      {
          Console.WriteLine("Name={0}, Phone={1}", item.Name, item.Phone);
      }

沒有留言:

張貼留言