【问题标题】:Why is the == operator (defined for the concrete type) not used?为什么不使用 == 运算符(为具体类型定义)?
【发布时间】:2011-04-27 11:48:29
【问题描述】:

我有一个列表定义为:

var Items = new List<IItem>();

现在有许多不同的类具有该接口,其中之一是 Consumable。 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 列表中拉出它们吗?

【问题讨论】:

标签: c# operator-overloading


【解决方案1】:

由于您的列表是List&lt;IItem&gt;,我假设您有类似的内容:

var item1 = Items[0];

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

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

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

你的演员实现了类似的目标。

另一种选择是确保==Equals(和GetHashCode())一致,并使用:

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        不应该是 IItem IComparable?

        【讨论】:

        • IComparable 用于排序,而不是相等。内置的Equals 是为了平等,如果你想要一个类型化的 API,IEquatable&lt;T&gt; 也是如此。
        猜你喜欢
        • 2012-06-14
        • 2021-06-11
        • 2021-11-30
        • 2013-12-04
        • 2020-10-10
        • 2020-12-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多