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

Effective C# 原則 28:避免轉換運算子(一)

     編輯:關於C語言

轉換運算子與替代性

轉換運算子是替代性型別間操作轉換。替代性即一個類別可取代另一個類別。這可能是好事:衍生類別物件可被基類物件取代,經典例子為形狀繼承。先有形狀類別,衍生出矩形、橢圓、圓形等。任何地方可用圖形取代圓形,這是多態替代性。正確因為圓形是特殊形狀。建立類別時,明確型別轉換可自動完成。.NET 類別繼承中 System.Object 為所有型別基類,故任何型別可用 System.Object 取代。同理,你建立的任何型別應可用其實作介面、基類介面或基類取代。不僅如此,C# 還支援其他轉換。

轉換運算子的潛在錯誤

為某型別添加轉換運算子,等於告訴編譯器:你的型別可被目標型別取代。這可能引發潛在錯誤,因你的型別很可能不能被目標型別取代(譯註:非指繼承關係轉換,而是 C# 允許的另一種轉換)。副作用:修改目標型別狀態後可能對原型別無效。更糟:若轉換產生暫時物件,副作用是直接修改暫時物件,永久丟失在 GC。總之,使用轉換運算子應基於編譯期型別物件,而非執行期型別物件。使用者可能需對型別進行多樣化強制轉換,產生難維護程式碼。

轉換運算子的合理用途

可用轉換運算子將未知型別轉換為你的型別,更清楚表現建立新物件操作(譯註:此轉換要建立新物件)。

範例:圓形與橢圓轉換

假設類別庫結構如圖 3.1。橢圓與圓皆繼承自形狀,雖信橢圓與圓相關,但決定保留此繼承關係(因不想在繼承中用非抽象葉子類別,從橢圓繼承圓有難題)。但意識到每個圓形應是橢圓,某些橢圓也可能是圓形。(圖 3.1)(譯註:作者例子不恰當,且前面假設原因,請讀者理解作者思想,別鑽牛角尖。相信你的 C# 開發中可能遇到類似轉換問題,只是不太可能從圓形轉橢圓。)

導致添加兩轉換運算子。每個圓形是橢圓,添加隱式轉換從圓形轉新橢圓。隱式轉換在類別要求轉換為另一類別時調用。對應顯式轉換為程式設計師在程式碼用強制轉換運算子。

public class Circle : Shape
{
    private PointF _center;
    private float _radius;
    public Circle() : this(PointF.Empty, 0) { }
    public Circle(PointF c, float r) { _center = c; _radius = r; }
    public override void Draw() { /*...*/ }
    static public implicit operator Ellipse(Circle c)
    {
        return new Ellipse(c._center, c._center, c._radius, c._radius);
    }
}

實作隱式轉換,可在任何要求橢圓地方使用圓形,轉換自動完成:

public double ComputeArea(Ellipse e) { /* return area */ }
Circle c = new Circle(new PointF(3.0f, 0), 5.0f);
ComputeArea(c);

表達可替代型別:圓形已可取代橢圓。ComputeArea 可在替代型別上工作。但看下例:

public void Flatten(Ellipse e) { e.R1 /= 2; e.R2 *= 2; }
Circle c = new Circle(new PointF(3.0f, 0), 5.0f);
Flatten(c);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved