为什么没有使用==运算符(针对具体类型定义)?

时间:2011-04-27 11:48:30

标签: c# operator-overloading

我有一个列表定义为:

var Items = new List<IItem>();

现在有许多不同的类具有该接口,其中一个是耗材。 Consumable类也有==运算符重载。现在我有以下代码并且无法正常工作:

if(item1 == item2)
{
    //code...
}

这不起作用。我在==运算符重载中设置了一个断点,它永远不会达到它。当我进行逐行调试时,item1和item2都是Consumable类型,GetType都返回Consumable。我甚至试过这段代码:

var temp = item1.GetType();
var temp2 = item2.GetType();
if (temp == temp2)
{
    //code...
}

并且这种平等结果是正确的。现在,如果我试试这个:

if(((Consumable)item1) == ((Consumable)item2))
{
    //code...
}

这会触发==运算符重载的断点。如果逐行调试显示它已经认为它们都是可消耗的,为什么我必须手动转换变量?是因为我从IItems列表中提取它们吗?

4 个答案:

答案 0 :(得分:10)

由于您的列表是List<IItem>,我假设您有类似的内容:

var item1 = Items[0];

或其他;此处item1 变量的输入为IItem。运算符解析在构建期间通过静态分析(不是在运行时通过多态/ RTTI)发生,因此唯一==可用是任何object的默认值,即引用相等。

要支持自定义运算符,必​​须相应地键入变量,例如:

Consumable item1 = ..., item2 = ...;

你的演员也达到了类似的目的。

另一种选择是确保==Equals(以及GetHashCode())达成一致,并使用:

if(Equals(item1, item2)) {...}

将执行null检查,然后使用重写的Equals方法。然后,这支持多态,因此类型是什么并不重要。

答案 1 :(得分:1)

常见的langauge运行时只知道你的两个对象实现了接口IItem。对象层次结构中最小的公共部分是System.Object。并且您没有重载System.Object的==运算符。

要使用正确的重载,您必须说明对象的类型。

答案 2 :(得分:0)

==不检查类型相等,但对于类,它检查引用相等性。因此,如果变量指向同一个对象,那将是真的。例如:

var temp = item1;
var temp2 = item1;

if( temp == temp2 )
{
  //this code will execute
}

答案 3 :(得分:0)

不应该是IItem IC Comparable?