2011-06-06 81 views
8

我敢肯定這是一個愚蠢的問題,但爲什麼下面的代碼不會調用顯式操作符在子類MyBool上強制轉換?C#顯式運算符和繼承

public class DataType 
{ 
    public static explicit operator bool(DataType D) 
    { 
     return false; 
    } 

    public static explicit operator DataType(bool B) 
    { 
     return new DataType(); 
    } 
} 

public class MyBool : DataType 
{ 
    public bool Value; 

    public MyBool() 
    { 
     Value = false; 
    } 

    public static explicit operator bool(MyBool B) 
    { 
     return B.Value; 
    } 

    public static explicit operator MyBool(bool B) 
    { 
     return new MyBool() { Value = B }; 
    } 
} 

則:

List<DataType> Types = new List<DataType>(); 

Types.Add(new MyBool() { Value = true }); 
Types.Add(new MyBool() { Value = false }); 

foreach (DataType T in Types) 
{ 
    bool Value = (bool)T; 
    MessageBox.Show(Value.ToString()); 
} 

產生輸出:假的,假的

是我寫在每個類的功能採取的明確操作功能的地方唯一的選擇?

+0

它的工作原理就像預期。 – leppie 2011-06-06 12:08:20

+1

我的問題是「爲什麼下面的代碼不會調用顯式操作符...?」不是「這個工作正常嗎?」。 – Andy 2011-06-07 09:53:34

回答

15

爲什麼下面的代碼不會在子類MyBool上調用顯式操作符來強制轉換?

由於操作功能static,因此也非virtual並且因此他們的目標是在編譯時而不是運行時解決。這是預期的行爲。

如果你想擁有的多態轉換操作符,你可以調用虛函數運營商:

public abstract class DataType 
{ 
    public static explicit operator bool(DataType D) 
    { 
     return D.DoCastToBool(); 
    } 

    public static explicit operator DataType(bool B) 
    { 
     // We haven’t got an instance of our class here. 
     // You can use a factory method pattern to emulate virtual constructors. 
    } 

    protected abstract bool DoCastToBool(); 
} 
2

運營商們超載而不是覆蓋 - 換句話說,在選擇哪個執行使用編制時間爲。編譯器只知道TDataType,所以它調用DataType中的運算符。

一種選擇是從MyBool刪除操作,但在DataType添加一個虛擬方法,允許多態行爲:

public class DataType 
{ 
    public static explicit operator bool(DataType D) 
    { 
     // TODO: Decide how you want to handle null references 
     return D.ToBoolean(); 
    } 

    protected virtual bool ToBoolean() 
    { 
     return false; 
    } 
} 

public class MyBool : DataType 
{ 
    // ... 

    protected override bool ToBoolean() 
    { 
     return Value; 
    } 
} 

注意這個會從bool的轉換不工作一個DataType,因爲在那種情況下,我們沒有任何關於您實際想要創建DataType的子類型的任何信息。

(邊注:您的代碼會更容易,如果你使用的正常.NET命名約定遵循)

+0

喬恩,在.NET版本中一直是這種情況?或者有一段時間.NET搜索繼承層次結構?我問,因爲與此有關的錯誤似乎與項目升級到更新的.NET一致。所討論的對象在編譯時鍵入爲'object',但運行時類型確實有操作符定義。我非常懷疑這種情況,但有人建議...... – Sprague 2013-03-06 16:26:36

+1

@Sprague:不,總是如此。 – 2013-03-06 16:28:34