本系列最後一篇,涵蓋建構函式約束、值型別/參考型別約束,並總結 C# 泛型核心特性與與 C++/Java 的差異。
where T : new()class A { public A() {} }
class B { public B(int i) {} }
class Factory where T : new()
{
public T Create() => new T(); // 僅限無參數建構函式
}
var f1 = new Factory(); // OK
var f2 = new Factory(); // 編譯錯誤:B 無無參數建構函式
public struct Point { public int X, Y; }
public class Entity { public string Name; }
class StructContainer where T : struct { } // 僅限值型別
class ClassContainer where T : class { } // 僅限參考型別
var s = new StructContainer(); // OK
var c = new ClassContainer(); // OK
// var err1 = new StructContainer(); // 錯誤
// var err2 = new ClassContainer(); // 錯誤
| 特性 | C# | C++ 模板 | Java 泛型 |
|---|---|---|---|
| 實作機制 | CLR 執行期實例化(Reified) | 編譯期程式碼展開 | 編譯期型別擦除 |
| 跨語言互通 | 支援(CLS) | 否 | 僅限 JVM 語言 |
| 程式碼膨脹 | 參考型別共享程式碼,值型別各自實例化 | 每種型別產生獨立程式碼 | 單一程式碼共享 |
| 反射支援 | 完整保留泛型中繼資料 | 無 | 擦除後無法反射 |
| 約束方式 | 基類、介面、建構函式、值/參考型別 | 鴨子類型(隱式簽名) | extends/super(上界/下界) |
| 泛型類型支援 | 類別、結構、介面、委派、方法 | 類別、函式 | 類別、介面、方法 |
List 產生機器碼,後續重用;List 共享參考型別程式碼;List、List 各自獨立。where 宣告型別能力,犧牲彈性換取型別安全與錯誤訊息可讀性。T 必須支援 +、== 等,需透過介面(IAddable)模擬。C# 泛型以 CLR 級支援實現型別安全、效能與互通性的平衡。掌握五大約束(基類、介面、建構函式、值型別、參考型別)與實例化機制,能撰寫高復用、高效能的泛型程式庫。