版本控制是「以兼容方式持續改進組件」的過程。兩種兼容性:
大多數語言不支持二進制兼容,甚至源代碼兼容也難保證。C# 通過強制開發者顯式聲明意圖解決此問題。本文對應規范第 1.13 節「版本控制」。
// 作者 A - Base.dll v1
namespace A { public class Base { } }
// 作者 B - Derived.dll v1 (引用 Base v1)
namespace B
{
public class Derived : A.Base
{
public virtual void F() { Console.WriteLine("Derived.F"); }
}
}
客戶部署 `Base.dll v1` + `Derived.dll v1`。
// 作者 A - Base.dll v2
namespace A
{
public class Base
{
public virtual void F() { Console.WriteLine("Base.F"); } // 新增
}
}
// Derived.dll v2a
public class Derived : A.Base
{
new public virtual void F() { Console.WriteLine("Derived.F"); } // 明確隱藏
}
// Derived.dll v2b
public class Derived : A.Base
{
public override void F()
{
base.F(); // 可選:調用基類實現
Console.WriteLine("Derived.F");
}
}
public class Derived : A.Base
{
public virtual void DoSomething() { ... } // 改名
}
| 場景 | 關鍵字 | 語義 | 兼容性影響 |
|---|---|---|---|
| 派生類成員與新增基類同名 | 無 (重新編譯) | 警告 + 默認隱藏 | 二進制兼容,源代碼重編譯有警告 |
| 明確隱藏 | `new` | 無關,僅同名 | 消除警告,語義明確 |
| 明確重寫 | `override` | 多態重寫 | 需基類 virtual/abstract,構成契約 |
| 基類成員非 virtual | 派生類同名 | 只能 `new` 隱藏 | 不可 `override` |
C# 版本控制的核心哲學是「顯式優於隱式」。通過強制 `new`/`override` 選擇,將潛在的脆弱繼承關係轉化為編譯期可驗證的契約。這保護了二進制兼容性 (舊程序集不重編譯照常運行),同時引導開發者在源代碼層面做出明確決策。理解「隱藏 vs 重寫」的語義差異、二進制與源代碼兼容的邊界、重命名的代價,是設計可長期演進框架的必修課。