06.C#泛型約束和高級泛型(三章3.3-3.4)


  吃午飯前繼上篇泛型再寫一篇關於泛型的文章,雖然總是被博客園移出首頁,文章不精確實是大問題啊,會再接再厲的。進入正題。

  先來說下泛型約束。當我們在使用泛型的時候通常會希望使用泛型實參時,參數能具備某一些特性,這時"泛型約束"來了,它能幫助我們在傳入泛型參數,該參數要實現先前指定的約束。有4種約束可用,如下:

  1. 引用類型約束:確保使用的類型參數是引用類型(T:class,且必須是類型參數指定的第一個約束),類型實參任何類、接口、數組、委托、或者已知是引用類型的另一個類型參數。
  2. 值類型約束:表示成(T:struct),可以確保使用的實參是值類型,包括枚舉(enums),但是它將可空類型排隊在外。
  3. 構造類型約束:表示成(T:new()),必須是約束的最后一個約束,它檢查類型是否具有一個可用於創建實例的無參構造函數。
  4. 轉換類型約束:允許你指定另一個類型,類型參數可以通過一致性引用或隱式轉換或裝箱轉換轉換為該類型。
1 public struct DoDo<T> where T : class
2 {}
3 public class BiBi<T> where T : struct
4 {}
5 public struct CoCo<T> where T : new()
6 {}
7 public struct DkDk<T> where T : System.Data.IDbConnection
8 {}

  上述四個分別對應四種類型約束(僅僅在單個使用),下面來說下在組合使用的情況。

  組合使用有兩點要注意:

  1.  如果存在多個輪換類型約束,並且其中一個是類,那么它應該出現在接口的前面,不能多次指定同一個接口。
  2. 當包含多個類型參數時,每一個類型約束都單獨使用一個where。
 1 //不能同時指定類型參數既是引用類型又是值類型
 2 //public struct DoDo<T> where T : class, struct
 3 //{}
 4 
 5 public class BiBi<T> where T : Stream, new()
 6 {}
 7 
 8 //使用構造類型約束,new()要放在最后
 9 //public class LiLi<T> where T : new(), Stream
10 //{}
11 
12 public struct CoCo<T> where T : class, IDisposable , new()
13 {}
14 
15 //如下一個約束是類,要放在接口的前面
16 //public struct FeFe<T> where T : IDisposable, class, new()
17 //{}

  使用泛型約束知識都在上面了,更多的去理解和消化。在使用泛型方法時,讓編譯器是推斷能讓我們的代碼更簡短,但可讀性可能不高。

  ------------------------------------------------------------------------------------------------------------------------------------------

  Point 1 關於靜態字段和靜態構造方法,每一個封閉類型有一個靜態字段,如果有的話

1 StaticConstraint<int> intStatic = new StaticConstraint<int>();
2 StaticConstraint<int>.StaticValue = "int";
3 
4 StaticConstraint<double> doubleStatic = new StaticConstraint<double>();
5 StaticConstraint<double>.StaticValue = "double";
6 
7 StaticConstraint<char> charStatic = new StaticConstraint<char>();
8 StaticConstraint<char>.StaticValue = "char";

   Point 2 使用typeof獲取類型

  typeof可通過兩種方式作用於泛型類型,一種用來獲取未綁定泛型類型,一種用來獲取特定的已構造類型。前一種需要提供泛型的名稱,去除所有類型參數的名稱,但要保留逗號,后一種需要采取與聲明泛型類型變量相同的方式指定類型參數即可。

  

 1 static void GetTypeOfConstraint<X>()
 2 {
 3         //獲取未綁定泛型類型
 4         Console.WriteLine(typeof(X));
 5         Console.WriteLine(typeof(List<>));
 6         Console.WriteLine(typeof(Dictionary<,>));
 7 
 8         //獲取已構造類型
 9         Console.WriteLine(typeof(List<int>));
10         Console.WriteLine(typeof(Dictionary<int, double>));
11 }

  請斧正。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM