程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 《CLR.via.C#第三版》第二部分第12章節 泛型 讀書筆記(六),

《CLR.via.C#第三版》第二部分第12章節 泛型 讀書筆記(六),

編輯:C#入門知識

《CLR.via.C#第三版》第二部分第12章節 泛型 讀書筆記(六),


終於講到泛型了。當初看到這個書名,最想看的就是作者對泛型,委托,反射這些概念的理解。很多人對泛型的理解停留在泛型集合上,剛開始我也是,隨著項目越做越多,對待泛型的認識也越來越深刻。

 

泛型的概念:泛型是一種特殊的類型,它把指定類型的工作推遲到客戶端代碼聲明並實例化類或方法的時候進行。

泛型的優勢:源代碼保護、類型安全、更加清晰的代碼、更佳的性能。

原理:(關鍵字:開放類型,封閉類型)所有帶泛型參數的類型都是一個開放式類型,它不能被實例化(類似接口),在具體使用時生成封閉類型(實際數據類型)。

泛型約束(至多一個主要約束,次要約束無限制):

     泛型約束的使用:

        /// <summary>
        /// 未加約束的T可以是任何類型,許多類型沒有提供CompareTo方法,沒有約束將導致代碼不能編譯,報"'T'不包含'CompareTo'的定義"錯誤
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o1"></param>
        /// <param name="o2"></param>
        /// <returns></returns>
        private static T Min<T>(T o1,T o2) where T : IComparable<T>
        {
            if (o1.CompareTo(o2) < 0) return o1;
            return o2;
        }

      構造器約束:

//因為所有值類型都隱式有一個公共無參構造器。約束要求指定的任何引用類型也要有一個公共無參構造器
internal sealed class ConstructorConstraint<T> where T:new(){
      public static T Factory(){
          return new T();
      }
}

      由於泛型類型參數不能指定以下特殊引用類型:System.Object,System.Array,System.Delegate,System.MulticastDelegate,System.ValueType,System.Enum,System.Void,一些實參限制的實現可能要“特殊處理”,如以下使用靜態構造器來保證類型是一個枚舉類型。

internal sealed class GenericTypeThatRequiresAnEnum<T>{
    static GenericTypeThatRequiresAnEnum(){
        if(!typeof(T).IsEnum){
             throw new ArgumentException("T must be an enumerated type");
        }
    }
}

泛型接口的優勢:沒有泛型接口,每次視圖使用一個非泛型接口來操作一個值類型,都會發生裝箱,而且會失去編譯時的類型安全性。

委托和接口的逆變和協變泛型類型實參:

不變量:意味著泛型類型參數不能更改。(常用)

逆變量:意味著泛型類型參數可以從一個基類更改為該類的派生類。在C#中,用in關鍵字標記逆變量形式的泛型類型參數。逆變量泛型類型參數只出現在輸入位置,比如作為方法的參數。

協變量:意味著泛型類型參數可以從一個派生類更改為它的基類。在C#中,是用out關鍵字標記協變量形式的泛型類型參數。協變量泛型類型參數只能出現在輸出位置,比如作為方法的返回類型。

public delegate TResult Func<in T,out TResult>(T arg);

其它重要認知:

類型實參的指定和繼承層次結構沒有任何關系--理解這一點,有助於你判斷轉型的進行。
C#允許使用簡化的語法來引用一個泛型封閉類型

using DateTimeList = System.Collections.Generic.List<System.DateTime>;

現在執行下面這行代碼時,sameType會被初始化為true:

Boolean sameType = (typeof(List<DateTime>) == typeof(DateTimeList));

CLR支持泛型委托,目的是保證任何類型的對象都能以一種類型安全的方式傳給一個回調方法。此外,泛型委托允許任何一個值類型實例在傳給一個回調方法時不執行任何裝箱處理。

一些驗證問題:

1. 泛型類型變量的轉型

將一個泛型類型的變量轉型為另一個類型是非法的,除非將其轉型為另一個約束兼容的類型

private static void CastingType<T>(T obj){
     Int32 x = (Int32)obj;//錯誤
     String s = (String)obj;//錯誤
     string s2 = obj as String;//無錯誤
}

2. 設定默認值

private static void SettingDefaultValue<T>(){
      T temp = default(T);
}

default關鍵字告訴C#編譯器和CLR的JIT編譯器,如果T是一個引用類型,就將temp設為null,如果T是一個值類型,就將temp的所有位設為0。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved