泛型型別參數的約束
在定義泛型類時,可以對用戶端代碼能夠在執行個體化類時用於型別參數的類型種類施加限制。如果用戶端代碼嘗試使用某個約束所不允許的類型來執行個體化類,則會產生編譯時間錯誤。這些限制稱為約束。約束是使用 where 內容關鍵字指定的。下表列出了六種類型的約束:
| 約束 |
說明 |
T:結構 |
型別參數必須是實值型別。可以指定除 { Track('ctl00_LibFrame_ctl06|ctl00_LibFrame_ctl07',this); }" href="http://msdn2.microsoft.com/zh-cn/library/system.nullable(VS.80).aspx">Nullable 以外的任何實值型別。有關更多資訊,請參見{ Track('ctl00_LibFrame_ctl06|ctl00_LibFrame_ctl08',this); }" href="http://msdn2.microsoft.com/zh-cn/library/2cf62fcy(VS.80).aspx">使用可空類型(C# 編程指南)。 |
T:類 |
型別參數必須是參考型別,包括任何類、介面、委託或數群組類型。 |
T:new() |
型別參數必須具有無參數的公用建構函式。當與其他約束一起使用時,new() 約束必須最後指定。 |
T:<基類名> |
型別參數必須是指定的基類或派生自指定的基類。 |
T:<介面名稱> |
型別參數必須是指定的介面或實現指定的介面。可以指定多個介面約束。約束介面也可以是泛型的。 |
T:U |
為 T 提供的型別參數必須是為 U 提供的參數或派生自為 U 提供的參數。這稱為裸類型約束。 |
{
ShowHideCollapsibleArea('ctl00_LibFrame_ctl17609f64e','ctl00_LibFrame_ctl17img');return false;
}" href="http://msdn2.microsoft.com/zh-cn/library/d5x73970(VS.80).aspx#">裸類型約束
用作約束的泛型型別參數稱為裸類型約束。當具有自己的型別參數的成員函數需要將該參數約束為包含類型的型別參數時,裸類型約束很有用,如下面的樣本所示:
class List<T>
{
code_collapse_toggle(this);
}" src="http://writeblog.csdn.net/Images/OutliningIndicators/ExpandedBlockStart.gif" alt="" align="top">{
code_collapse_toggle(this);
}" src="http://writeblog.csdn.net/Images/OutliningIndicators/ContractedBlock.gif" alt="" align="top">{
{
code_collapse_toggle(this);
}" src="http://writeblog.csdn.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" alt="" align="top">{
code_collapse_toggle(this);
}" src="http://writeblog.csdn.net/Images/OutliningIndicators/ContractedSubBlock.gif" alt="" align="top"> void Add<U>(List<U> items) where U : T {/**//**/}
}
在上面的樣本中,T 在 Add 方法的上下文中是一個裸類型約束,而在 List 類的上下文中是一個未綁定的型別參數。
裸類型約束還可以在泛型類定義中使用。注意,還必須已經和其他任何型別參數一起在角括弧中聲明了裸類型約束:
//naked type constraintpublic class SampleClass<T, U, V> where T : V { }
泛型類的裸類型約束的作用非常有限,因為編譯器除了假設某個裸類型約束派生自 System.Object 以外,不會做其他任何假設。在希望強制兩個型別參數之間的繼承關係的情況下,可對泛型類使用裸類型約束。
{
Track('ctl00_LibFrame_ctl09|ctl00_LibFrame_ctl10',this);
}" href="http://msdn2.microsoft.com/zh-cn/library/0x6a29h6(VS.80).aspx">泛型介紹(C# 編程指南)中)的功能。