// 合法繼承鏈
class Base { }
class Derived : Base { }
class Generic where T : Base { } // T 必須繼承 Base
class Generic2 where T : new() { } // T 必須有無參數建構函式
class Generic3 where T : struct { } // T 必須為值型別
class Generic4 where T : class { } // T 必須為參考型別
class Generic5 where T : IDisposable { } // T 必須實作介面
// 非法:class Bad : Generic { } // int 不符合 class 約束
泛型介面與變異數
// 協變: out T (唯讀) IEnumerable
interface IReader { T Read(); }
IReader r = new CatReader(); // 合法
// 逆變: in T (唯寫) IComparer
interface IWriter { void Write(T item); }
IWriter w = new AnimalWriter();
IWriter w2 = w; // 合法
泛型委派
delegate bool Predicate(T value);
delegate TResult Func(T arg);
// 使用
Predicate isEven = i => i % 2 == 0;
Predicate isLong = s => s.Length > 10;
泛型方法
public static int FindIndex(T[] array, T item) where T : IEquatable
{
for (int i = 0; i < array.Length; i++)
if (array[i].Equals(item)) return i;
return -1;
}
// 呼叫時型別推論
int idx = FindIndex(new[] { 1, 3, 5 }, 5); // T 推論為 int
abstract class Entity { public Guid Id { get; protected set; } }
class Repository where T : Entity
{
public T GetById(Guid id) => _db.Set().Find(id);
public void Add(T entity) => _db.Set().Add(entity);
}
介面約束:演算法需特定能力
public T Max(IEnumerable source) where T : IComparable
=> source.Aggregate((a, b) => a.CompareTo(b) > 0 ? a : b);
建構函式約束:工廠模式
public T Create() where T : new() => new T();
// 錯誤: Create(); // FileStream 無無參數建構函式
值/參考型別約束:效能與語意
// 僅接受值型別,避免 null 與裝箱
struct NullableWrapper where T : struct { public T? Value; }
// 僅接受參考型別,利用 null 語意
class RefHolder where T : class { public T Instance; }