C#泛型約束


本文將對各類泛型約束做一個簡單的總結。

文章一開始,給出演示代碼底稿(在此基礎上修改,演示,說明。)

class MyList<T> { List<T> list = new List<T>(); public T this[int i] { get { return list[i]; } set { this.list[i] = value; } } } class Person { public string Name { get; set; } }

接下來,依次修改演示代碼底稿,來說明不同類型的泛型約束。

1 指定泛型參數為值類型

class MyList<T> where T:struct { ...代碼省略部分 }

看看加上約束后的效果怎么樣,按下面方式 實例化MyList 類 :

MyList<Person> list = new MyList<Person>();

你會發現,將產生如下錯誤提示:

類型“GencConstraint.Person”必須是不可為 null 的值類型才能用作泛型類型或方法“GencConstraint.MyList<T>”中的參數“T”。

使用下面的方式實例化MyList 類 ,將一切正常:

MyList<int> list = new MyList<int>();

 

2  指定泛型參數為引用類型

class MyList<T> where T:class { ...代碼省略部分 }

修改泛型約束為 引用類型后,前面的錯誤提示消失,因為 Person 類是引用類型,滿足泛型約束。

 

3  指定泛型參數有無參的公共的構造函數

class MyList<T> where T:new() { ...代碼省略部分 }

為Person類增加私有的無參構造函數,代碼如下:

class Person { public string Name { get; set; } private Person() { //do nothing } }

實例化 MyList < Person > 類:

MyList<Person> list = new MyList<Person>();

出現編譯錯誤,提示:

“GencConstraint.Person”必須是具有公共的無參數構造函數的非抽象類型,才能用作泛型類型或方法“GencConstraint.MyList<T>”中的參數“T”。

哈哈,約束起作用了。

 

4  指定泛型參數 必須派生於指定基類

增加抽象類 SeniorAnimal

abstract class SeniorAnimal//高級動物 { public abstract void Speak();//會說話 public abstract void UseTool();//會使用工具 }

指定泛型參數 必須派生於基類 SeniorAnimal

class MyList<T> where T : SeniorAnimal { ...代碼省略部分 }

實例化 MyList < Person > 類(此時Person類還未繼承自 SeniorAnimal 類 ):

MyList<Person> list = new MyList<Person>();

出現編譯錯誤,提示:

不能將類型“GencConstraint.Person”用作泛型類型或方法“GencConstraint.MyList<T>”中的類型參數“T”。沒有從“'GencConstraint.Person”到“GencConstraint.SeniorAnimal”的隱式引用轉換。

修改代碼,使Person類繼承自 SeniorAnimal 類

class Person : SeniorAnimal { public string Name { get; set; } public override void Speak() { Console.WriteLine("我會說臟話!"); } public override void UseTool() { Console.WriteLine("我會用砍刀!"); } }

再次編譯,一切正常。

5 指定泛型參數 必須實現指定接口

演示情況和第4點類似,就不提供演示代碼了。

6  指定泛型參數 必須派生於泛型類型U(裸類型約束)

class MyList<U> where U : SeniorAnimal { List<U> list = new List<U>(); public void ShowInfo<T>() where T : U { } }

 

 

另外,可以為同一泛型參數應用多個約束。

 

好了,Game Over!


免責聲明!

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



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