首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 泛型核心優勢與實戰模式:型別安全、效能、重用

     編輯:關於C語言

前言

泛型是 C# 2.0 引入的里程碑特性,解決了 object / ArrayList 時代的「型別不安全」與「裝箱/拆箱效能損耗」雙重痛點。本文深入剖析泛型的三大核心優勢、約束機制、變異數、常見陷阱與實戰設計模式。

一、為什麼需要泛型?

痛點object/ArrayList 時代泛型解決方案
型別安全編譯期不報錯,執行期 InvalidCastException編譯期強型別檢查
效能值型別頻繁裝箱/拆箱,堆疊/堆疊切換開銷大值型別零裝箱,專用程式碼共用
程式碼重用為每個型別寫專屬集合/演算法單一實作服務所有型別

二、泛型類別/介面/方法/委派語法速覽


// 泛型類別
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保證成員存在
不可為 nullnotnull (C# 8+)非 nullable 參考/值型別
可為 nulldefault / unmanaged特殊場景

// 多重約束
public class Service 
    where T : class, IComparable, new()
    where U : struct, IEquatable
{ }

四、協變數與逆變數

  • out (協變數):IEnumerable — 只作為輸出,IEnumerable 可隱含轉為 IEnumerable。
  • in (逆變數):Action — 只作為輸入,Action 可隱含轉為 Action。
  • 不變數:List — 同時輸入輸出,不可轉換。

IEnumerable objs = new List(); // 合法 (out)
Action actStr = (s) => Console.WriteLine(s);
Action actObj = actStr; // 合法 (in) — 只要能處理 object,一定能處理 string


五、實戰設計模式

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();
    }
}

六、效能深度解析