重新認識C#..

知識積累,重新回味下知識也許會有不少新認識..

1,C# 委託

委託:   是一種引用方法的類型。一旦爲委託分配了方法,委託將與該方法具有完全相同的行爲。委託方法的使用可以像其他任何方法一樣,具有參數和返回值
  將方法作爲參數進行引用的能力使委託成爲定義回調方法的理想選擇。例如,可以向排序算法傳遞對比較兩個對象的方法的引用。分離比較代碼使得可以採用更通用的方式編寫算法。

委託概述

          委託具有以下特點:

           委託類似於 C++ 函數指針,但它是類型安全的。

           委託允許將方法作爲參數進行傳遞。

           委託可用於定義回調方法。

           委託可以鏈接在一起;例如,可以對一個事件調用多個方法。

           方法不需要與委託簽名精確匹配。

           C# 2.0 版引入了匿名方法的概念,此類方法允許將代碼塊作爲參數傳遞,以代替單獨定義的方法。 

C# 1.0聲明委託
          public delegate void Del<T>(T item);
          public void Notify(int i) { }

使用委託
          Del<int> d1 = new Del<int>(Notify);

C#2.0使用委託
         Del<int> d2 = Notify;

C#3.0以上版本可以使用Lambda表達式來取代C#2.0裏面的匿名委託

         Action<int> d3 = s => s;

下面分別做下比較

   

public class DelegateExample
   {
       //命名委託
       delegate void Del(int i, double j);
       //匿名委託
       delegate void Printer(string s);
       public static void Run()
       {
           //C#2.0之前的命名方法委託
           Del dl = MultiplyNumbers;
           for (int i = 0; i < 5; i++)
           {
               dl(i,2);
           }
           //C#2.0引入了匿名方法--匿名方法的參數的範圍是匿名方法塊
           Printer print = delegate(string p) { Console.WriteLine(p); };
           //使用匿名委託
           print("匿名函數");
           //使用命名方法的委託
           print = new Printer(DoWork);
           print("命名方法委託");
 
           // C# 3.0 及更高版本中,Lambda 表達式取代了匿名方法
           //上面的例子可以改爲Action有參數但無返回值的,如果是有返回值的用Func<>
           Action<string> funcprint = s => Console.WriteLine(s);
           funcprint("Lambda表達式");
           Console.ReadKey();
       }
       static void MultiplyNumbers(int i, double j)
       {
           Console.WriteLine("i * j  = " + i * j);
       }
       static void DoWork(string p)
       {
           Console.WriteLine(p);
       }
   }



   

2,Lambda

“Lambda 表達式”是一個匿名函數,它可以包含表達式和語句,並且可用於創建委託或表達式樹類型。 所有 Lambda 表達式都使用 Lambda 運算符 =>,該運算符讀爲“goes to”。 該 Lambda 運算符的左邊是輸入參數(如果有),右邊包含表達式或語句塊。 Lambda 表達式 x => x * x 讀作“x goes to x times x”。可以將此表達式分配給委託類型.

       delegate int del(int i);       static void Main(string[] args)
       {           del myDelegate = x => x * x;           int j = myDelegate(5); //j = 25       }

創建表達式樹類型:

using System.Linq.Expressions;namespace ConsoleApplication1
{    class Program    {        static void Main(string[] args)
        {            Expression<del> myET = x => x * x;
        }
    }
}

Lambda 的一般規則如下:

        Lambda 包含的參數數量必須與委託類型包含的參數數量相同。

        Lambda 中的每個輸入參數必須都能夠隱式轉換爲其對應的委託參數。

        Lambda 的返回值(如果有)必須能夠隱式轉換爲委託的返回類型。

        Lambda 表達式本身沒有類型,因爲常規類型系統沒有“Lambda 表達式”這一內部概念。但是,有時會不正式地論及 Lambda 表達式的“類型”。 在這些情況下,類型是指委託類型或 Lambda 表達式所轉換爲的 Expression 類型。


  

//此處顯示了一個Lambda標準查詢運算
      int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
      //篩選出滿足該條件的唯一元素
      int oddNumbers = numbers.Single(n => n  == 0);
      Console.WriteLine(oddNumbers.ToString());
      //只要滿足條件就會返回元素
      var fielNumbers = numbers.TakeWhile(n => n < 8);
      foreach (var item in fielNumbers)
      {
          Console.WriteLine(item.ToString());
      }
 


    

C# 2.0規範中提到的匿名方法規範同樣適用於Lambda表達式。Lambda表達式是匿名方法在功能行上的超集,提供了下列附加的功能:

l         Lambda表達式允許省略參數類型並對其進行推斷,而匿名方法要求參數類型必須顯式地聲明。

l         Lambda表達式體可以是表達式或語句塊,而匿名方法體只能是語句塊。

l         在類型參數推導和方法重載抉擇時,Lambda表達式可以被作爲參數傳遞。

l         以一個表達式作爲表達式體的Lambda表達式可以被轉換爲表達式樹。

表達式樹類型:表達式樹表示樹狀數據結構的代碼,樹狀結構中的每個節點都是一個表達式,例如一個方法調用或類似 x < y 的二元運算。

表達式樹是Lambda表達式的一種高效的內存中數據表現形式,並且使得表達式的結構變得透明和明顯。

C# Lambda表達式樹要點:

                1. Lambda表達式的參數類型可以忽略,因爲可以根據使用的上下文進行推斷。
                2. Lambda表達式的主體(body)可以是表達式,也可以是語句塊。
                3. Lambda表達式傳入的實參將參與類型推斷,以及方法重載辨析。
                4. Lambda表達式和表達式體可以被轉換爲表達式樹。
                5. 表達式樹允許lambda表達式能夠代表數據結構替代表示爲執行代碼。

           Expression<Func<int, int>> expression = x => x + 5;           Console.WriteLine(expression.Parameters[0]);           Console.WriteLine(expression.Body);           //執行Expression表達式           Func<int, int> fx = expression.Compile();           Console.WriteLine(fx(5));


   

3,Linq

LINQ 提供一種跨各種數據源和數據格式使用數據的一致模型,所有 LINQ 查詢操作都由以下三個不同的操作組成: 獲取數據源。創建查詢。執行查詢。

   

public static void Run()
        {
            //用 Linq執行簡單的數組查詢
            int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
 
            //延遲執行
            //var numberQuery = from num in numbers
            //                  where (num % 2) == 0
            //                  select num;
 
            //強制立即執行
            List<int> numberQuery = (from num in numbers
                                     where (num % 2) == 0
                                     select num).ToList();
            //或者
            var numberArray = (from num in numbers
                               where (num % 2) == 0
                               select num).ToArray();
 
            //查詢變量本身只是存儲查詢命令。實際的查詢執行會延遲到在 foreach 語句中循環訪問查詢變量時發生。此概念稱爲“延遲執行”
            foreach (var item in numberQuery)
            {
                Console.WriteLine(item);
            }
        }


  

//本篇介紹Linq對集合的各種查詢
      public static void Run()
      {
          List<Customers> customerlist = new List<Customers>();
          customerlist.Add(new Customers() { id = 1, Name = "Jack", Custom = "Mis" });
          customerlist.Add(new Customers() { id = 2, Name = "Lus", Custom = "Google" });
          customerlist.Add(new Customers() { id = 3, Name = "Qiao", Custom = "Baidu" });
          customerlist.Add(new Customers() { id = 4, Name = "Qiao", Custom = "Apple" });
          customerlist.Add(new Customers() { id = 5, Name = "Adb", Custom = "Adobe" });
 
          //簡單的查詢
          var customerQuery = from query in customerlist
                              select query;
 
          //帶where篩選
          var customerWhereQuery = from query in customerlist
                                   where query.id == 1 && query.Name == "Lus"
                                   select query;
 
          //排序Ordering
          var customerOrderingQuery = from query in customerlist
                                      where query.Name == "Lus"
                                      orderby query.id ascending
                                      select query;
 
          //分組Group by
          var customerGroupbyQuery = from query in customerlist
                                     group query by query.Name;
          //可以使用into進一步查詢
          var customerGroupbyIntoQuery = from query in customerlist
                                         group query by query.Name into queryGroup
                                         where queryGroup.Key == "Qiao"
                                         select queryGroup;
          //聯接查詢 join 子句始終針對對象集合而非直接針對數據庫表運行。
          List<Customers> customerJoinlist = new List<Customers>();
          customerJoinlist.Add(new Customers() { id = 1, Name = "Jack", Custom = "Mis" });
          customerJoinlist.Add(new Customers() { id = 2, Name = "Lus", Custom = "Google" });
          customerJoinlist.Add(new Customers() { id = 3, Name = "Qiao", Custom = "Baidu" });
          var customerJoinQuery = from query1 in customerlist
                                  join query2 in customerJoinlist
                                  on query1.id equals query2.id
                                  select new { CustomerName = query1.Name, CustomerName2 = query2.Name };
 
          //數據源的類型參數始終爲查詢中的範圍變量的類型。
          //比如List<Customers> 類型爲Customers 在循環迭代的時候類型必須可以隱式轉換爲Customer 有一種情況是
          //這種情況下Customers類型轉換爲了String ..在select query.Name已經將查詢目標類型定位了String類型
          var customerTypeQuery = from query in customerlist
                                  where query.Name == "Lus"
                                  select query.Name;
 
          //結合Lamdba對List集合篩選(s => s.Name == "Qiao")
          List<Customers> listString = customerlist.Where(s => s.Name == "Qiao").ToList();
 
 
      }
  }
 
  public class Customers
  {
      public int id { get; set; }
 
      public string Name { get; set; }
 
      public string Custom { get; set; }
  }


  

Linq To SQL

首先連接NORTHWRN數據庫 爲了做列子簡單的把Customers表拖放到dbml文件.也就是LinqToSQL類

public static void Run()
      {
          DataClasses1DataContext dataContext = new DataClasses1DataContext();
 
          //對Customers數據源執行簡單查詢
          var custQuery = from custom in dataContext.Customers
                          where custom.City == "Seattle"
                          select custom;
          //添加實體
          Customers customers = new Customers()
          {
              ContactName = "AdventureWorks Cafe",
              Address = "Google",
              CustomerID = "ADVAS"
          };
          dataContext.Customers.InsertOnSubmit(customers);
 
          //更新實體
          var updateCustomer = (from c in dataContext.Customers
                                where c.CustomerID == "ADVAS"
                                select c).First();
          updateCustomer.ContactName = "New Name";
          //提交更改
          dataContext.SubmitChanges();
 
          //刪除實體
          List<Customers> deleteCustomer = (from c in dataContext.Customers
                               where c.id >= 1000
                               select c).ToList();
          //批量刪除
          dataContext.Customers.DeleteAllOnSubmit(deleteCustomer);
      }


      

4,Dynamic

     Visual C# 2010 引入了一個新類型 dynamic。 該類型是一種靜態類型,但類型爲 dynamic 的對象會跳過靜態類型檢查。 大多數情況下,該對象就像具有類型 object 一樣。 在編譯時,將假定類型化爲 dynamic 的元素支持任何操作。 因此,您不必考慮對象是從 COM API、從動態語言(例如 IronPython)、從 HTML 文檔對象模型 (DOM)、從反射還是從程序中的其他位置獲取自己的值。但是,如果代碼無效,則在運行時會捕獲到錯誤。  

    在通過 dynamic 類型實現的操作中,該類型的作用是繞過編譯時類型檢查, 改爲在運行時解析這些操作。該類型簡化了對 COM API(例如 Office Automation API)、例動態 API(如 IronPython 庫)和 HTML 文檔對象模型 (DOM) 的訪問。

    在大多數情況下, dynamic 類型與 object 類型的行爲是一樣的。 但是,不會用編譯器對包含 dynamic 類型表達式的操作進行解析或類型檢查。 編譯器將有關該操作信息打包在一起,並且該信息以後用於計算運行時操作。在此過程中,類型 dynamic 的變量會編譯到類型 object 的變量中。 因此,類型 dynamic 只在編譯時存在,在運行時則不存在。

public class DynamicExample
    {
        public static void Run()
        {
            dynamic dyn = "j";
            object obj = 1;
            dynamic dyng = GetDyn("哈哈");
 
            //運行時檢查
            Console.WriteLine((dyn + 3).GetType());
            //編譯報錯
            //Console.WriteLine(obj + 3);
            Console.WriteLine(dyng + " " + dyng.GetType());
        }
 
        public static dynamic GetDyn(object obj)
        {
            return obj;
        }
    }

    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章