C# 允許定義隱性/顯性轉換運算子,宣告型別可替換性。但這往往引發難以發現的 Bug:
public class Circle : Shape {
static public implicit operator Ellipse(Circle c)
=> new Ellipse(c._center, c._center, c._radius, c._radius);
}
呼叫 Flatten(Ellipse e) 並傳入 Circle 時:
Flatten 修改此暫時物件。Circle 物件完全未被修改,暫時物件隨即成為垃圾。改為顯性轉換 (Ellipse)c 同樣產生暫時物件,問題依舊。
// 明確建立新 Ellipse,語意清晰,呼叫端知曉產生新物件
Flatten(new Ellipse(c));
進一步追蹤變數更佳:
Ellipse e = new Ellipse(c);
Flatten(e); // 保留修改後的 e
回傳內部欄位的轉換運算子,等於公開內部實作細節,違反封裝原則(參見原則 23)。
轉換運算子提供型別替換假象,實則引入暫時物件副作用、封裝洩漏、難以除錯的行為。應盡量避免使用,改用建構函式或工廠方法明確表達物件建立意圖。