2011-12-07 36 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; 
} 
相关问题