LINQ

在說LINQ之前必須先說說幾個重要的C#語言特性

一:與LINQ有關的語言特性

  1.隱式類型

    (1)源起

      在隱式類型出現之前,

      我們在聲明一個變量的時候,

      總是要爲一個變量指定他的類型

      甚至在foreach一個集合的時候,

      也要爲遍歷的集合的元素,指定變量的類型

      隱式類型的出現,

      程序員就不用再做這個工作了。

    (2)使用方法

       來看下面的代碼:    

  var a = 1; //int a = 1;
      var b = "123";//string b = "123"; 
      var myObj = new MyObj();//MyObj myObj = new MyObj()

      上面的每行代碼,與每行代碼後面的註釋,起到的作用是完全一樣的

      也就是說,在聲明一個變量(並且同時給它賦值)的時候,完全不用指定變量的類型,只要一個var就解決問題了

    (3)你擔心這樣寫會降低性能嗎?

      我可以負責任的告訴你,這樣寫不會影響性能!

      上面的代碼和註釋裏的代碼,編譯後產生的IL代碼(中間語言代碼)是完全一樣的

      (編譯器根據變量的值,推導出變量的類型,才產生的IL代碼)      

    (4)這個關鍵字的好處:

      你不用在聲明一個變量並給這個變量賦值的時候,寫兩次變量類型

      (這一點真的爲開發者節省了很多時間)

      在foreach一個集合的時候,可以使用var關鍵字來代替書寫循環變量的類型

     (5)注意事項

      你不能用var關鍵字聲明一個變量而不給它賦值

      因爲編譯器無法推導出你這個變量是什麼類型的。

  2.匿名類型

    (1)源起

      創建一個對象,一定要先定義這個對象的類型嗎?

      不一定的!

      來看看這段代碼

    (2)使用 

  var obj = new {Guid.Empty, myTitle = "匿名類型", myOtherParam = new int[] { 1, 2, 3, 4 } };
     Console.WriteLine(obj.Empty);//另一個對象的屬性名字,被原封不動的拷貝到匿名對象中來了。
     Console.WriteLine(obj.myTitle);
     Console.ReadKey();   new關鍵字之後就直接爲對象定義了屬性,並且爲這些屬性賦值

      而且,對象創建出來之後,在創建對象的方法中,還可以暢通無阻的訪問對象的屬性

      當把一個對象的屬性拷貝到匿名對象中時,可以不用顯示的指定屬性的名字,這時原始屬性的名字會被“拷貝”到匿名對象中

    (3)注意    

      如果你監視變量obj,你會發現,obj的類型是Anonymous Type類型的

      不要試圖在創建匿名對象的方法外面去訪問對象的屬性!

    (4)優點

      這個特性在網站開發中,序列化和反序列化JSON對象時很有用

  3.自動屬性

    (1)源起

      爲一個類型定義屬性,我們一般都寫如下的代碼: 複製代碼
    public class MyObj2
    {
    private Guid _id;
    private string _Title;
    public Guid id
    {
    get { return _id; }
    set { _id = value; }
    }
    public string Title
    {
    get { return _Title; }
    set { _Title = value; }
    }
    }
複製代碼   但很多時候,這些私有變量對我們一點用處也沒有,比如對象關係映射中的實體類。

      自C#3.0引入了自動實現的屬性,

      以上代碼可以寫成如下形式:

    (2)使用

    public class MyObj
    {
        public Guid id { get; set; }
        public string Title { get; set; }
    }

      這個特性也和var關鍵字一樣,是編譯器幫我們做了工作,不會影響性能的

  4.初始化器

    (1)源起

      我們創建一個對象並給對象的屬性賦值,代碼一般寫成下面的樣子    

        var myObj = new MyObj();
        myObj.id = Guid.NewGuid();
        myObj.Title = "allen";

      自C#3.0引入了對象初始化器,

      代碼可以寫成如下的樣子

    (2)使用    

      var myObj1 = new MyObj() { id = Guid.NewGuid(), Title = “allen” };
      如果一個對象是有參數的構造函數

      那麼代碼看起來就像這樣

      var myObj1 = new MyObj (“allen”) { id = Guid.NewGuid(), Title = “allen” };
      集合初始化器的樣例代碼如下:    

      var arr = new List() { 1, 2, 3, 4, 5, 6 };
    (3)優點

      我個人認爲:這個特性不是那麼amazing,

      這跟我的編碼習慣有關,集合初始化器也就罷了,

      真的不習慣用對象初始化器初始化一個對象!

  5.委託

    (1)使用

      我們先來看一個簡單的委託代碼    

複製代碼
    delegate Boolean moreOrlessDelgate(int item);
    class Program
    {
    static void Main(string[] args)
    {
    var arr = new List() { 1, 2, 3, 4, 5, 6,7,8 };
    var d1 = new moreOrlessDelgate(More);
    Print(arr, d1);
    Console.WriteLine(“OK”);

            var d2 = new moreOrlessDelgate(Less);
            Print(arr, d2);
            Console.WriteLine("OK");
            Console.ReadKey();

        }
        static void Print(List<int> arr,moreOrlessDelgate dl)
        {
            foreach (var item in arr)
            {
                if (dl(item))
                {
                    Console.WriteLine(item);
                }
            }
        }
        static bool More(int item)
        {
            if (item > 3)
            { 
                return true; 
            }
            return false;
        }
        static bool Less(int item)
        {
            if (item < 3)
            {
                return true;
            }
            return false;
        }
    }

複製代碼
      這段代碼中

      <1>首先定義了一個委託類型

        delegate Boolean moreOrlessDelgate(int item);

        你看到了,委託和類是一個級別的,確實是這樣:委託是一種類型

        和class標誌的類型不一樣,這種類型代表某一類方法。

        這一句代碼的意思是:moreOrlessDelgate這個類型代表返回值爲布爾類型,輸入參數爲整形的方法

      <2>有類型就會有類型的實例  

        var d1 = new moreOrlessDelgate(More);    
        var d2 = new moreOrlessDelgate(Less);
        這兩句就是創建moreOrlessDelgate類型實例的代碼,

        它們的輸入參數是兩個方法

      <3>有了類型的實例,就會有操作實例的代碼   

        Print(arr, d1);
        Print(arr, d2);
        我們把前面兩個實例傳遞給了Print方法

        這個方法的第二個參數就是moreOrlessDelgate類型的

        在Print方法內用如下代碼,調用委託類型實例所指向的方法

        dl(item)

  6.泛型

    (1)爲什麼要有泛型

      假設你是一個方法的設計者,

      這個方法有一個傳入參數,有一個返回值。

      但你並不知道這個參數和返回值是什麼類型的,

      如果沒有泛型,你可能把參數和返回值的類型都設定爲Object了

      那時,你心裏肯定在想:反正一切都是對象,一切的基類都是Object

      沒錯!你是對的!

      這個方法的消費者,會把他的對象傳進來(有可能會做一次裝箱操作)

      並且得到一個Object的返回值,他再把這個返回值強制類型轉化爲他需要的類型

      除了裝箱和類型轉化時的性能損耗外,代碼工作的很好!

      那麼這些新能損耗能避免掉嗎?

      有泛型之後就可以了!

    (2)使用

      <1>使用簡單的泛型

        先來看下面的代碼:        

複製代碼
  var intList = new List() { 1,2,3};
  intList.Add(4);
  intList.Insert(0, 5);
  foreach (var item in intList)
  {
  Console.WriteLine(item);
  }
  Console.ReadKey();
複製代碼
        在上面這段代碼中我們聲明瞭一個存儲int類型的List容器

        並循環打印出了容器裏的值

        注意:如果這裏使用Hashtable、Queue或者Stack等非泛型的容器

        就會導致裝箱操作,損耗性能。因爲這些容器只能存儲Object類型的數據

      <2>泛型類型

        List、Dictionary

   from p in db.Employees
             select new
             {
                 LastName = p.LastName,
                 TitleOfCourtesy = p.TitleOfCourtesy
             } into EmployeesList
             orderby EmployeesList.TitleOfCourtesy ascending
             select EmployeesList;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章