1. 程式人生 > >c# 泛型T型別引數T的約束where

c# 泛型T型別引數T的約束where

在定義泛型類時,可以對客戶端程式碼能夠在例項化類時用於型別引數的型別種類施加限制。如果客戶端程式碼嘗試使用某個約束所不允許的型別來例項化類,則會產生編譯時錯誤。這些限制稱為約束。約束是使用 where 上下文關鍵字指定的。下表列出了六種型別的約束:

約束

說明

T:結構

型別引數必須是值型別。可以指定除 Nullable 以外的任何值型別。有關更多資訊,請參見使用可空型別(C# 程式設計指南)。

T:類

型別引數必須是引用型別,包括任何類、介面、委託或陣列型別。

Tnew()

型別引數必須具有無引數的公共建構函式。當與其他約束一起使用時,new() 約束必須最後指定。

T<基類名>

型別引數必須是指定的基類或派生自指定的基類。

T<介面名稱>

型別引數必須是指定的介面或實現指定的介面。可以指定多個介面約束。約束介面也可以是泛型的。

TU

為 提供的型別引數必須是為 提供的引數或派生自為 提供的引數。這稱為裸型別約束。


使用約束的原因

如果要檢查泛型列表中的某個項以確定它是否有效,或者將它與其他某個項進行比較,則編譯器必須在一定程度上保證它需要呼叫的運算子或方法將受到客戶端程式碼可能指定的任何型別引數的支援。這種保證是通過對泛型類定義應用一個或多個約束獲得的。例如,基類約束告訴編譯器:僅此型別的物件或從此型別派生的物件才可用作型別引數。一旦編譯器有了這個保證,它就能夠允許在泛型類中呼叫該型別的方法。約束是使用上下文關鍵字 where 

應用的。

泛型約束基本上有五種:

值型別約束:要求泛型引數必須是值型別,例如int,short以及自定義的stuct等
    public class MyClass2<T> 
        where T : struct//這個泛型類只接受值型別的泛型引數 
    { 
    }

引用型別約束:要求泛型引數必須是引用型別,例如string,object,以及自定義的class
    public class MyClass<T> 
        where T:class//這個泛型類只接受引用型別的泛型引數 
    { 
    }

建構函式約束:要求泛型引數必須有建構函式
    public class MyClass3<T> 
        where T : new() 
    { 
    }

介面約束:要求泛型引數必須實現某個介面
    public class MyClass4<T> 
        where T : System.IComparable 
    { 
    }

基類約束:要求泛型引數必須繼承某個基類
    public class MyClass5<T> 
        where T : Customer 
    { 
    }