2011-12-07 42 views
1

爲什麼C#允許將對象隱式轉換爲用於等式比較的int,但不允許將對象類型轉換爲對象類型比較,即使存在隱式運算符?爲什麼進行相等性檢查,不允許隱式轉換對象類型,但對於int?

bool errorHere = valueOnly == valuePair;一行在底部給出例外。

class Program 
{ 
    static void Main(string[] args) 
    { 
     ValueOnly valueOnly = new ValueOnly(); 
     ValuePair valuePair = new ValuePair(); 
     bool areEqual = valueOnly.Value == valuePair; 
     bool errorHere = valueOnly == valuePair; 
     bool butNotHere = valueOnly == (ValueOnly)valuePair; 
     valueOnly = valuePair; // Or Here 
    } 
} 

public class ValuePair 
{ 
    public int Value { get; set; } 
    public string Text { get; set; } 

    public static implicit operator ValueOnly(ValuePair valuePair) { 
     if (valuePair.Text != null || valuePair.Value != 0) { 
      return new ValueOnly() { Value = valuePair.Value }; 
     } 
     return null; 
    } 

    public static implicit operator int(ValuePair valuePair) { 
     return valuePair.Value; 
    } 
} 

public class ValueOnly 
{ 
    public int Value { get; set; } 
} 

以下是錯誤:

Error Operator '==' cannot be applied to operands of type 'ValueOnly' and 'ValuePair' 

回答

1

C#肯定不允許的對象的隱式轉換爲int S代表任何目的。我不確定您是否指

bool butNotHere = valueOnly == (ValueOnly)valuePair; 

作爲「允許」這樣的轉換。如果是這樣,它不會做任何這樣的事情。它只是調用你自己的轉換運算符(如果我正確地讀取代碼將返回null,因爲該值將是一個默認構造的整數),然後做兩個對象之間的引用比較(其結果爲false,因爲null不是引用 - 等於任何東西)。

不言而喻,一旦您定義了一個隱式轉換運算符,C#將在必要時使用它。因此,我認爲你的問題需要做更多的事情來理解等式運算符是如何基於它的參數類型而工作的。

更新,對於valueOnly == valuePair檢查:

C#的規格,7.10.6(引用類型相等運算符)指出:

It is a binding-time error to use the predefined reference type equality operators to compare two references that are known to be different at binding-time. For example, if the binding-time types of the operands are two class types A and B, and if neither A nor B derives from the other, then it would be impossible for the two operands to reference the same object. Thus, the operation is considered a binding-time error.

如果你想能夠比較的類的對象鍵入等號,最好的方法是實現IEquatable<T>接口,並覆蓋object.Equals以實現IEquatable<T>.Equals(這意味着你也必須覆蓋object.GetHashCode)以匹配。

但是,在比較項目時依靠「隱藏」轉換是個壞主意。如果我們正在談論比較無關的班級,那麼通過儘可能突出地進行比較,您將爲自己節省很多痛苦。爲此,我建議低技術

if(valuePair.Value == valueOnly.Value) 
+0

也許我是說錯了,但如果是這樣,爲什麼這個工作? 「bool areEqual = valueOnly.Value == valuePair;」 valueOnly上的Value屬性是一個int,並且valuePair被隱式轉換爲一個int ... – Daryl

+0

您引用的行正在使用定義的隱式運算符執行顯式轉換。我想真正的問題是,爲什麼我必須明確定義轉換? – Daryl

+1

@Daryl:在再次閱讀您的問題後修改。你必須明確地定義從'ValuePair'到'ValueOnly'的轉換,因爲這兩種類型是不相關的。 – Jon

0

爲了讓valueOnly == valuePair你必須把它添加到ValuePair類:

public static bool operator == (ValueOnly valueOnly, ValuePair valuePair){ 
    ValueOnly value = valuePair; 
    return valueOnly.Value == value.Value; 
} 

這裏使用了隱式轉換,然後執行平等檢查我在找...

而現在,我想起來了,隱式轉換是愚蠢的(因爲我沒有給ValueOnly類提供一個相等運算符):

public static bool operator == (ValueOnly valueOnly, ValuePair valuePair){ 
    return valueOnly.Value == valuePair.Value; 
} 
相關問題