为什么不使用==操作符(为具体类型定义)
本文关键字:类型 定义 操作符 为什么不 | 更新日期: 2023-09-27 17:53:05
我有一个列表定义为:
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...
}
,这会触发==操作符重载中的断点。为什么我必须手动转换变量,如果逐行调试显示它已经认为它们都是可消费的?是因为我从iitem列表中提取它们吗?
由于您的列表是List<IItem>
,我假设您有如下内容:
var item1 = Items[0];
之类的;这里item1
变量的类型为IItem
。操作符解析在构建过程中通过静态分析进行(而不是在运行时通过多态性/RTTI),因此唯一可用的==
是任何object
的默认值,即引用相等。
为了支持您的自定义操作符,变量必须相应地键入,例如:
Consumable item1 = ..., item2 = ...;
你的cast达到了类似的效果。
另一个选择是确保==
和Equals
(和GetHashCode()
)一致,并使用:
if(Equals(item1, item2)) {...}
将执行null
检查,然后使用覆盖的Equals
方法。这样就支持多态,所以类型是什么并不重要。
公共语言运行时只知道您的两个对象实现接口IItem。对象层次结构中最小的公共部分是System.Object。您没有重载System.Object的==操作符。
要使用正确的重载,必须声明对象的类型。
==不检查类型是否相等,但对于类,它检查引用是否相等。所以如果两个变量都指向同一个对象,它就为真。例如:
var temp = item1;
var temp2 = item1;
if( temp == temp2 )
{
//this code will execute
}
IItem不应该具有可比性吗?