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

Effective C# 原則 29:僅在基類強制更新導致名稱衝突時使用 new 修飾詞

     編輯:關於C#

new 修飾詞:隱藏繼承成員的雙面刃

new 修飾詞可在衍生類別中重新定義非虛擬繼承成員。但這會導致語意混淆:同一物件透過不同型別參考呼叫同名方法,卻執行不同程式碼。

非虛擬 vs 虛擬:靜態繫結 vs 動態分派

public class MyClass { public void MagicMethod() { ... } }
public class MyOtherClass : MyClass { public new void MagicMethod() { ... } }

object c = new MyOtherClass();
((MyClass)c).MagicMethod();   // 呼叫 MyClass 版本(靜態繫結)
((MyOtherClass)c).MagicMethod(); // 呼叫 MyOtherClass 版本

這違反「同一物件同一行為」直覺,造成維護噩夢。

最佳實務:優先設計虛擬函式

  • 基類庫設計者應預判衍生需求,將可變更行為設計為 virtual。
  • 虛擬函式集合定義「預期可覆寫的行為契約」,引導衍生類別正確擴充。
  • 避免使用 new 重新定義非虛擬成員。

唯一合理使用情境:第三方基類更新導致名稱衝突

情境:你開發 MyWidget : BaseWidget,已發布廣泛使用。廠商更新 BaseWidget 新增 DoWidgetThings(),導致編譯衝突。

// 方案 1:改名(若掌握所有原始碼,長遠最佳)
public class MyWidget : BaseWidget { public void DoMyWidgetThings() { ... } }

// 方案 2:使用 new(已發布元件,無法要求用戶改碼)
public class MyWidget : BaseWidget { public new void DoWidgetThings() { ... } }

警示: 即使此情境,new 仍留下長期語意模糊。若用戶需呼叫基類版本,問題依存。短痛(改名)優於長痛(語意模糊)。

結論

new 修飾詞極度謹慎使用,僅限「無法控制基類且基類更新導致衝突」的緊急情境。其他任何場合均應避免,改用虛擬函式機制或重新命名。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved