C#泛型約束
六種型別的約束:
格式 | 描述 |
---|---|
T:結構 | 型別引數必須是值型別。可以指定除 Nullable 以外的任何值型別。有關更多資訊,請參見使用可空型別(C# 程式設計指南)。 |
T:類 | 型別引數必須是引用型別,包括任何類、介面、委託或陣列型別。 |
T:new() | 型別引數必須具有無引數的公共建構函式。當與其他約束一起使用時,new() 約束必須最後指定。 |
T:<基類名> | 型別引數必須是指定的基類或派生自指定的基類。 |
T:<介面名稱> | 型別引數必須是指定的介面或實現指定的介面。可以指定多個介面約束。約束介面也可以是泛型的。 |
T:U | 為 T 提供的型別引數必須是為 U 提供的引數或派生自為 U 提供的引數。這稱為裸型別約束。 |
例子:
1.介面約束。
例如,可以宣告一個泛型類 MyGenericClass
,這樣,型別引數 T
就可以實現 IComparable<T>
介面:
public class MyGenericClass<T> where T:IComparable { }
2.基類約束。
指出某個型別必須將指定的類作為基類(或者就是該類本身),才能用作該泛型型別的型別引數。這樣的約束一經使用,就必須出現在該型別引數的所有其他約束之前。
class MyClassy<T, U>
where T : class
where U : struct
{
}
3.建構函式約束。
以使用 new
運算子建立型別引數的例項;但型別引數為此必須受建構函式約束new()
的約束。new()
約束可以讓編譯器知道:提供的任何型別引數都必須具有可訪問的無引數(或預設)建構函式。new()
約束出現在 where
子句的最後。
public class MyGenericClass <T> where T: IComparable, new()
{
// The following line is not possible without new() constraint:
T item = new T();
}
4.對於多個型別引數,每個型別引數都使用一個 where
子句。
interface MyI { }
class Dictionary<TKey,TVal>
where TKey: IComparable, IEnumerable
where TVal: MyI
{
public void Add(TKey key, TVal val)
{
}
}
5.還可以將約束附加到泛型方法的型別引數。
public bool MyMethod<T>(T t) where T : IMyInterface { }
6. 裸型別約束
用作約束的泛型型別引數稱為裸型別約束。當具有自己的型別引數的成員函式需要將該引數約束為包含型別的型別引數時,裸型別約束很有用。
class List<T>
{
void Add<U>(List<U> items) where U : T {/*...*/}
}
泛型類的裸型別約束的作用非常有限,因為編譯器除了假設某個裸型別約束派生自 System.Object
以外,不會做其他任何假設。在希望強制兩個型別引數之間的繼承關係的情況下,可對泛型類使用裸型別約束。
7.default
關鍵字
之所以會用到default
關鍵字,是因為需要在不知道型別引數為值型別還是引用型別的情況下,為物件例項賦初值。考慮以下程式碼:
class TestDefault<T>
{
public T foo()
{
T t = null; //???
return t;
}
}
如果我們用int
型來繫結泛型引數,那麼T
就是int
型,那麼註釋的那一行就變成了 int t = null;
顯然這是無意義的。為了解決這一問題,引入了default
關鍵字:
class TestDefault<T>
{
public T foo()
{
return default(T);
}
}
相關文章
- Go 泛型之泛型約束Go泛型
- C#中泛型約束(where)是什麼?C#泛型
- 泛型的約束理解泛型
- [譯]Kotlin泛型中何時該用型別形參約束?Kotlin泛型型別
- Java泛型(三):型別擦除帶來的約束與侷限性Java泛型型別
- C#泛型C#泛型
- 【C#】-泛型C#泛型
- C# 泛型C#泛型
- C#泛型集合C#泛型
- 【.NET】利用 IL 魔法實現隨心隨意的泛型約束泛型
- 學員優秀博文賞析:泛型萬用字元及約束泛型字元
- C#泛型學習C#泛型
- 淺談C#泛型C#泛型
- 詳解C#泛型(一)C#泛型
- 詳解C#泛型(三)C#泛型
- 詳解C#泛型(二)C#泛型
- 【SQL】15 SQL 約束(Constraints)、NOT NULL 約束、UNIQUE 約束、PRIMARY KEY 約束、FOREIGN KEY 約束、CHECK 約束、DEFAULT約束SQLAINull
- 資料型別與約束資料型別
- C#泛型鍵值對集合C#泛型
- C#基礎:泛型委託C#泛型
- 理解C#泛型運作原理C#泛型
- C# 泛型集合的自定義型別排序C#泛型型別排序
- C#學習 [型別系統] 泛型(16)C#型別泛型
- C#快速入門教程(21)—— 泛型C#泛型
- C#類繼承自泛型集合C#繼承泛型
- c#——泛型的多種應用C#泛型
- 深度學習中的Lipschitz約束:泛化與生成模型深度學習模型
- SQL教程——常見的約束型別SQL型別
- Go 泛型變更:約束太醜了,先移動到 x/exp 做實驗性功能Go泛型
- C#規範整理·泛型委託事件C#泛型事件
- 約束
- Javaweb-約束-外來鍵約束JavaWeb
- 泛型類、泛型方法及泛型應用泛型
- 【java】【泛型】泛型geneticJava泛型
- C# 泛型中的資料型別判定與轉換C#泛型資料型別
- C#中的介面和泛型集合探討C#泛型
- TreeSet的null值與元素型別的約束Null型別
- 32. 基本資料型別、約束條件資料型別