// 泛型類別
public class Repository where T : class, IEntity, new()
{
public void Add(T entity) { /* ... */ }
public T GetById(int id) => default;
}
// 泛型介面
public interface IRepository where T : class
{
T Find(int id);
void Save(T item);
}
// 泛型方法 (型別推論)
public static void Swap(ref T a, ref T b) { T t = a; a = b; b = t; }
// 呼叫:Swap(ref x, ref y); // 編譯器推論 T
// 泛型委派
public delegate TResult Func(T arg); // 變異數:in/contra, out/co
三、型別參數約束
約束
語法
意義
參考型別
class
排除值型別
值型別
struct
排除 nullable、reference
無參建構子
new()
允許 new T()
基底類別
BaseClass
限定繼承鏈
介面
IInterface
保證成員存在
不可為 null
notnull (C# 8+)
非 nullable 參考/值型別
可為 null
default / unmanaged
特殊場景
// 多重約束
public class Service
where T : class, IComparable, new()
where U : struct, IEquatable
{ }
四、協變數與逆變數
out (協變數):IEnumerable — 只作為輸出,IEnumerable 可隱含轉為 IEnumerable。
in (逆變數):Action — 只作為輸入,Action 可隱含轉為 Action。
不變數:List — 同時輸入輸出,不可轉換。
IEnumerable
五、實戰設計模式
1. Repository 模式 + 泛型基底
public abstract class RepositoryBase : IRepository where T : class, IEntity
{
protected readonly DbContext _ctx;
public RepositoryBase(DbContext ctx) => _ctx = ctx;
public virtual T GetById(int id) => _ctx.Set().Find(id);
public virtual void Add(T entity) => _ctx.Set().Add(entity);
}
public class UserRepository : RepositoryBase { /* User 專屬查詢 */ }
2. 策略模式 + 泛型工廠
public interface IExporter { string Export(T data); }
public class CsvExporter : IExporter { public string Export(T d) => "csv"; }
public class JsonExporter : IExporter { public string Export(T d) => "json"; }
public static class ExporterFactory
{
private static readonly Dictionary _map = new();
public static void Register(IExporter exporter) => _map[typeof(T)] = exporter;
public static IExporter Get() => (IExporter)_map[typeof(T)];
}
// 使用
ExporterFactory.Register(new CsvExporter());
var exporter = ExporterFactory.Get();
3. 管線/中介軟體模式
public interface IMiddleware
{
Task InvokeAsync(TContext ctx, Func next);
}
public class Pipeline
{
private readonly List> _mid = new();
public Pipeline Use(IMiddleware m) { _mid.Add(m); return this; }
public async Task RunAsync(TContext ctx)
{
Func next = () => Task.CompletedTask;
for (int i = _mid.Count - 1; i >= 0; i--)
{
var current = _mid[i];
var n = next;
next = () => current.InvokeAsync(ctx, n);
}
await next();
}
}
// 非泛型
var list = new ArrayList();
list.Add(1); // 裝箱 int → object
int x = (int)list[0]; // 拆箱
// 泛型
var list = new List();
list.Add(1); // 直接寫入陣列,零裝箱
int x = list[0]; // 直接讀取