C# 2.0 泛型實現了類型參數化,在編譯期保證類型安全,運行期避免裝箱拆箱,JIT 按需生成專用代碼,兼顧性能與復用性。本文系統講解泛型類、接口、委託、方法、繼承規則及四大約束機制。
public class Test // 兩個類型參數
{
private T _name;
private S _age;
public Test(T name, S age)
{
_name = name;
_age = age;
}
public void Print()
{
Console.WriteLine($"Name: {_name}, Age: {_age}");
}
}
// 實例化時指定具體類型
Test t = new Test("張三", 25);
t.Print(); // Name: 張三, Age: 25
// 模式 1:父類類型參數已具體化 → 子類可為非泛型
public class ChildConcrete : Test { }
// 模式 2:父類類型參數來自子類 → 子類必須為泛型且參數匹配
public class ChildGeneric : Test { }
// 也可部分固定
public class ChildPartial : Test { }
❌ 非法:public class BadChild : Test — 父類類型參數無來源
// 定義
public interface IList { T[] GetElements(); }
public interface IDictionary { void Add(K key, V value); }
// 實現類需滿足同樣繼承規則
public class MyList : IList, IDictionary
{
public T[] GetElements() => new T[0];
public void Add(int key, T value) { /* ... */ }
}
// 定義:類型參數可用於參數、返回值
public delegate string Transformer(T input);
// 使用
Transformer toHex = n => n.ToString("X");
Transformer toUpper = s => s.ToUpper();
Console.WriteLine(toHex(255)); // FF
Console.WriteLine(toUpper("abc")); // ABC
public class Util
{
// 方法級類型參數
public T GetDefault() => default(T);
public void Swap(ref T a, ref T b)
{
T temp = a; a = b; b = temp;
}
}
// 調用時指定類型參數
Util u = new Util();
int val = u.GetDefault(); // 0
string str = u.GetDefault(); // null
int x = 1, y = 2;
u.Swap(ref x, ref y); // 類型推斷為 int
public class Base
{
public virtual T Process(T input, K key) where T : K => input;
}
public class Derived : Base
{
// 覆蓋時約束自動繼承,不可修改
public override T Process(T input, K key) => input;
}
where 子句提供四類顯式約束:
class Animal { public void Breath() => Console.WriteLine("Breathing"); }
class Dog : Animal { }
class Zoo where T : Animal // T 必須繼承 Animal
{
public void Check(T animal) => animal.Breath(); // 可調用基類方法
}
interface IPrintable { void Print(); }
interface IKeyProvider { string GetKey(); }
class Repository
where K : IComparable // K 可比較
where V : IPrintable, IKeyProvider // V 實現多接口
{
public void Save(K key, V value)
{
key.CompareTo(key); // 調用接口方法
value.Print();
value.GetKey();
}
}
class Factory where T : new() // T 必須有公共無參構造函數
{
public T Create() => new T(); // 可實例化
}
class A { public A() { } }
class B { public B(int x) { } } // 無無參構造函數
Factory fa = new Factory(); // OK
fa.Create();
// Factory fb = new Factory(); // 編譯錯誤
struct Point { public int X, Y; }
class Entity { }
class Processor where T : struct { } // T 必須為值類型
class Manager where T : class { } // T 必須為引用類型
Processor p = new Processor(); // OK
// Processor e = new Processor(); // 錯誤
Manager m = new Manager(); // OK
// Manager p2 = new Manager(); // 錯誤
List、List 獨立)List、List 共用)List<T>、Dictionary<K,V> 替代 ArrayList/Hashtablewherevoid Save<T>(T entity) 不如 void Save(Entity entity) 清晰微軟官方 WebCast 視頻教程(李建忠講師):
C# 2.0 泛型深度解析系列
掌握泛型是進階 C# 開發者的必修課,它不僅是語法特性,更是靜態類型系統表達能力的質飛躍。建議從集合類源碼(List<T>、Dictionary<K,V>)入手,觀察實際項目中的泛型應用模式。