【发布时间】:2009-10-08 23:40:23
【问题描述】:
我这里说的是 C# 语言。
msdn中Object.Equals(Object)方法的定义是:
判断是否指定 对象等于当前对象。
如果两个对象相等,则返回 true,如果它们为 null,则返回 false:
x.Equals(一个空引用 (Nothing in Visual Basic)) 返回 false。
为什么?因为 null 不是对象。
如果对象参数为空,则抛出 NullReferenceException。
我们还有这个:
x.Equals(y) 返回与 y.Equals(x)。
到这里完全没问题。它与 Java 非常相似。但是 C# 还为不可为空的类型提供了一个 System.Nullable 结构。据我所知,结构是一个对象。它继承了 Object.Equals 方法。
如果我有这样的结构:
struct Car
{
public string Make;
public string Model;
public uint Year;
public Car(string make, string model, uint year)
{
Make = make;
Model = model;
Year = year;
}
}
并创建四个实例:
Car car1 = new Car("make", "model", 2009);
Car car2 = new Car("make", "model", 2009);
Car car3 = new Car("make", "model", 2008);
car1.Equals(car2); // will return true
car1.Equals(car3); // will return false;
据我所知,我们不能将结构设置为空值。但是 System.Nullable 是一个结构体,我们可以编译它而不会出现任何错误:
int? i = null;
(我也希望有人能解释一下。是结构体还是别的什么?)
我真正的问题是:
i.Equals(null); // returns true!
(通常 x.Equals(y) = y.Equals(x) 当然 null.Equals(i) 在这里无效...)
很明显 Object.Equals 方法在这里被覆盖了。也许它已记录在案并且已指定。但是这种方法正确/不错吗?如果是这样,== 和 Equals 方法对于 Nullable 值有什么区别?
【问题讨论】:
-
回答您的最后一个问题。如果
Car? ncar1 = ...;是Nullable<>,那么ncar1 == null和ncar1.Equals(null)通常是相同的。两者都会检查ncar1.HasValue是否为false。但是如果我们也有Car? ncar2 = ...;,那么ncar1 == ncar2和ncar1.Equals(ncar2)可能会有所不同,这取决于Car结构类型是否重载operator ==.Equals的重载(可能是.Equals(object)被Car覆盖,或者只是被System.ValueType覆盖,或者如果声明了重载,则可能是.Equals(Car))。