public class Dictionary<K, V>
{
public void Add(K key, V value)
{
if (key.CompareTo(x) < 0) { } // 編譯錯誤:K 不保證有 CompareTo
}
}
K 可能為任何型別,僅能呼叫 object 定義的方法(ToString 等)。
if (((IComparable)key).CompareTo(x) < 0) { }
編譯通過,但執行期若傳入未實作 IComparable 的型別 → InvalidCastException。
使用 where 關鍵字編譯期強制檢查:
public class Dictionary<K, V> where K : IComparable
{
public void Add(K key, V value)
{
if (key.CompareTo(x) < 0) { } // 安全呼叫
}
}
傳入未實作 IComparable 的型別 → 編譯錯誤,提前攔截。
public class EntityTable<K, E>
where K : IComparable<K>, IPersistable // 多介面約束
where E : Entity, new() // 基類別 + 無參建構函式
{
public void Add(K key, E entity)
{
if (key.CompareTo(x) < 0) { }
E newEntity = new E(); // 允許建立實例
}
}
| 語法 | 含義 |
|---|---|
where T : BaseClass | T 必須繼承自 BaseClass(最多一個類別) |
where T : Interface | T 必須實作介面(可多個) |
where T : new() | T 必須有 public 無參建構函式 |
where T : class | T 必須為參考型別 |
where T : struct | T 必須為值型別(排除 Nullable) |
where T : U | T 必須為 U 或其衍生型別(型別參數約束) |
where T : notnull | T 不可為可為 null 的型別 (C# 8.0+) |
where T : unmanaged | T 為非受控型別 (C# 7.3+) |
where T : default | 覆寫繼承而來的約束 (C# 9.0+) |
// 若 List 约束 T : IComparable
List<MyClass> list = new List<MyClass>(); // MyClass 未實作 IComparable → 編譯失敗
// 即使不呼叫 Sort() 也無法使用
設計時需權衡:約束提供型別安全與功能,但限制適用型別範圍。
new() 約束適用於 Factory 模式、物件池where T : unmanaged 進行高效能記憶體操作