常用約束
約束告知編譯器型別引數必須具備的功能, 在沒有任何約束的情況下,型別引數可以是任何型別, 編譯器只能假定 System.Object 的成員,它是任何 .NET 型別的最侄訓類, 如果客戶端代碼使用不滿足約束的型別,編譯器將發出錯誤, 通過使用 where 背景關系關鍵字指定約束, 下表列出了七種型別的約束:
| 約束 | 描述 |
|---|---|
| where T : struct | 型別引數必須是不可為 null 的值型別, 有關可為 null 的值型別的資訊,請參閱可為 null 的值型別, 由于所有值型別都具有可訪問的無引數建構式,因此 struct 約束表示 new() 約束,并且不能與 new() 約束結合使用, struct 約束也不能與 unmanaged 約束結合使用, |
| where T : class | 型別引數必須是參考型別,此約束還應用于任何類、介面、委托或陣列型別, 在 C#8.0 或更高版本中的可為 null 背景關系中,T 必須是不可為 null 的參考型別, |
| where T : class? | 型別引數必須是可為 null 或不可為 null 的參考型別, 此約束還應用于任何類、介面、委托或陣列型別, |
| where T : notnull | 型別引數必須是不可為 null 的型別, 引數可以是 C# 8.0 或更高版本中的不可為 null 的參考型別,也可以是不可為 null 的值型別, |
| where T : unmanaged | 型別引數必須是不可為 null 的非托管型別,unmanaged 約束表示 struct 約束,且不能與 struct 約束或 new() 約束結合使用, |
| where T : new() | 型別引數必須具有公共無引數建構式,與其他約束一起使用時,new() 約束必須最后指定, new() 約束不能與 struct 和 unmanaged 約束結合使用, |
| where T : <base class name> | 型別引數必須是指定的基類或派生自指定的基類, 在 C# 8.0 及更高版本中的可為 null 背景關系中,T 必須是從指定基類派生的不可為 null 的參考型別, |
| where T : <base class name>? | 型別引數必須是指定的基類或派生自指定的基類,在 C# 8.0 及更高版本中的可為 null 背景關系中,T 可以是從指定基類派生的可為 null 或不可為 null 的型別, |
| where T : <interface name> | 型別引數必須是指定的介面或實作指定的介面,可指定多個介面約束, 約束介面也可以是泛型,在 C# 8.0 及更高版本中的可為 null 背景關系中,T 必須是實作指定介面的不可為 null 的型別, |
| where T : <interface name>? | 型別引數必須是指定的介面或實作指定的介面,可指定多個介面約束,約束介面也可以是泛型,在 C# 8.0 中的可為 null 背景關系中,T 可以是可為 null 的參考型別、不可為 null 的參考型別或值型別,T 不能是可為 null 的值型別, |
| where T : U | 為 T 提供的型別引數必須是為 U 提供的引數或派生自為 U 提供的引數,在可為 null 的背景關系中,如果 U 是不可為 null 的參考型別,T 必須是不可為 null 的參考型別,如果 U 是可為 null 的參考型別,則 T 可以是可為 null 的參考型別,也可以是不可為 null 的參考型別, |
最常用的泛型約束為where T : struct、where T : class、where T : new(),
約束多個引數
可以對多個引數應用多個約束,對一個引數應用多個約束,如下例所示:
class Base { }
class Test<T, U>
where U : struct
where T : Base, new()
{ }
對型別引數使用 == 和 != 運算子
在應用 where T : class 約束時,請避免對型別引數使用 == 和 != 運算子,編譯器只知道 T 在編譯時是參考型別,并且必須使用對所有參考型別都有效的默認運算子,
如果必須測驗值相等性,建議同時應用 where T : IEquatable
參考文章
型別引數的約束(C# 編程指南)——Microsoft
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/1632.html
標籤:C#
上一篇:設計模式之裝飾模式
