一、泛型約束
預設情況下,泛型的型別引數可以是任何型別的。
為什麼要使用型別引數的約束呢?
簡單點說就是篩選型別引數,在使用泛型的**中如果違反了某個約束不允許的型別來例項化則會產生編譯錯誤,型別引數的約束是使用關鍵字where。 下面列出了6中型別的約束
泛型約束有以下幾種:
where t:base-class //表示必須是某個父類的紫烈
where t:inte***ce //表示必須實現某個介面 ,當然一般這樣自身就是類
where t:class //表示必須是引用型別
where t:struct //表示必須是值型別,不包括可空型別
where t:new() //表示必須有乙個無引數的建構函式
whereu:t //u必須繼承於t
舉例:class mylist
set }}
class person
}接下來,依次修改演示**底稿,來說明不同型別的泛型約束。
1、 指定泛型引數為值型別
class mylistwhere t:struct
看看加上約束後的效果怎麼樣,按下面方式 例項化mylist 類 :
型別「gencconstraint.person」必須是不可為 null 的值型別才能用作泛型型別或方法「gencconstraint.mylist」中的引數「t」。
使用下面的方式例項化mylist 類 ,將一切正常:
mylistlist = new mylist();
2 、 指定泛型引數為引用型別
class mylistwhere t:class
修改泛型約束為 引用型別後,前面的錯誤提示消失,因為 person 類是引用型別,滿足泛型約束。
3 、 指定泛型引數有無參的公共的建構函式
class mylistwhere t:new()
為person類增加私有的無參建構函式,**如下:
class person
private person()
}例項化 mylist < person > 類:
「gencconstraint.person」必須是具有公共的無引數建構函式的非抽象型別,才能用作泛型型別或方法「gencconstraint.mylist」中的引數「t」。
哈哈,約束起作用了。
4、 指定泛型引數 必須派生於指定基類
增加抽象類 senioranimal
abstract class senioranimal//高階動物
指定泛型引數 必須派生於基類 senioranimal
class mylistwhere t : senioranimal
例項化 mylist < person > 類(此時person類還未繼承自 senioranimal 類 ):
不能將型別「gencconstraint.person」用作泛型型別或方法「gencconstraint.mylist」中的型別引數「t」。沒有從「'gencconstraint.person」到「gencconstraint.senioranimal」的隱式引用轉換。
修改**,使person類繼承自 senioranimal 類
class person : senioranimal
public override void speak()
public override void usetool()
}再次編譯,一切正常。
5、 指定泛型引數 必須實現指定介面
演示情況和第4點類似,就不提供演示**了。
6 、 指定泛型引數 必須派生於泛型型別u(裸型別約束)
class mylistwhere u : senioranimal
}另外,可以為同一泛型引數應用多個約束。
c 泛型約束
在定義泛型類時,可以對客戶端 能夠在例項化類時用於型別引數的型別種類施加限制。如果客戶端 嘗試使用某個約束所不允許的型別來例項化類,則會產生編譯時錯誤。這些限制稱為約束。約束是使用 where 上下文關鍵字指定的。下表列出了六種型別的約束 約束說明 t struct 型別引數必須是值型別。可以指定除...
C 泛型約束
約束告知編譯器型別引數必須具備的功能。在沒有任何約束的情況下,型別引數可以是任何型別。編譯器只能假定 system.object 的成員,它是任何 net 型別的最終基類。有關詳細資訊,請參閱使用約束的原因。如果客戶端 嘗試使用約束所不允許的型別來例項化類,則會產生編譯時錯誤。通過使用where上下...
C 泛型約束
范型中注意要用default返回預設值。范型約束where可以約束指定泛型型別是某種類或某種結構體,只能指定預設建構函式的約束不能指定其它形式的建構函式的約束,介面不能指定操作符過載。where t struct t是值型別 where t class t是引用型別 where t ifoo t必須...