C# 是可为空的<;T>;。Equals方法实现错误?
我这里说的是C语言 is中Object.Equals(Object)方法的定义: 确定指定的 对象等于当前对象 如果两个对象相等,则返回true;如果为null,则返回false: x、 等于(空引用)(在 visualbasic返回false 为什么??因为null不是一个对象 如果对象参数为null,则引发NullReferenceException 我们还有: x、 Equals(y)返回的值与 y、 等于(x) 在这里之前没问题。它与Java非常相似。但是C#还为不可为空的类型提供了一个C# 是可为空的<;T>;。Equals方法实现错误?,c#,oop,C#,Oop,我这里说的是C语言 is中Object.Equals(Object)方法的定义: 确定指定的 对象等于当前对象 如果两个对象相等,则返回true;如果为null,则返回false: x、 等于(空引用)(在 visualbasic返回false 为什么??因为null不是一个对象 如果对象参数为null,则引发NullReferenceException 我们还有: x、 Equals(y)返回的值与 y、 等于(x) 在这里之前没问题。它与Java非常相似。但是C#还为不可为空的类型提供了一个
System.Nullable
struct。据我所知,结构是一个对象。它继承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)当然为空。Equals(i)在这里无效…)
显然,Object.Equals方法在这里被重写。可能是有文件记录的,这是规定的。但是这种方法正确/好吗?如果是这样的话,可为空值的==和Equals方法之间的区别是什么?我认为您的困惑源于以下几行
i? = null;
这实际上并不创建空值变量。它本质上是合成糖,用于以下用途
Nullable<int> i = new Nullable<int>();
Nullable<int> i = new Nullable<int>();
i.Equals(null);
Nullable i=new Nullable();
结果属性HasValue on i的值为false。它不是null,而是一个具有空值的值类型。或者只是一个空的null。对于任何给定的T,最好的方法是将null转换为空的null
知道它使行i.Equals(null)更容易理解。这是一种合成糖,用于以下用途
Nullable<int> i = new Nullable<int>();
Nullable<int> i = new Nullable<int>();
i.Equals(null);
Nullable i=new Nullable();
i、 等于(空);
类型
Nullable
仅覆盖等于(对象)。但是,此方法的实现将空值视为等于空的可空值。所以它的行为是正确的。为了回答您的附带问题,Nullable是一个带有T:struct约束的结构。那么,即使int?i=零;如果为null,则i是可空结构的实例。但是,无论它在后台做什么,我们都将其称为i.Equals(null),当i为null时,它返回true。对于任何其他对象,它都应该返回false。@jcasso,可空的通常是。。。古怪的,经常以意想不到的方式表现。部分混淆是我不能为null,因为它实际上是一个值类型。最好将其视为一个空的可空值。至少你承认这很奇怪:)我认为我是唯一的一个。请注意,静态方法Object.Equals(null,null)
将返回true,因此公认null
等于null
。调用null.Equals(y)
时得到NullReferenceException
的唯一原因是引用类型上的实例方法调用的语义要求;它与等于本身的语义无关。因为Nullable
不是引用类型,所以这不适用。正如我在另一篇文章中指出的,I.Equals(null)没有调用Object.Equals。这是一个限制为可空类型的虚拟调用。结构可以接受空值吗?你能定义car4=null?就CLR而言,结构不能有null
值。在C#中,当您编写int时?x=null
,您实际上正在编写int?x=新整数?()
。这里根本没有真正的null
。但是当你做int的时候?i=,CLR将该合法值放入i的value属性中。另外,仅供参考,Nullable覆盖Equals方法,查看调用int下面的IL?i=零;CLR加载它分配给变量的地址,然后将一个空的可空对象(带有空字段)初始化到该地址。@pavel:用更简洁的方式来回答你的上一个问题,我在第二条注释中想说什么:)。如果汽车?ncar1=
是一个null的
,然后ncar1==null
和ncar1。Equals(null)
通常是相同的。两者都只需检查ncar1.HasValue
是否为false
。但是如果我们也有车?ncar2=
,然后ncar1==ncar2
和ncar1.Equals(ncar2)
可能不同,这取决于Car
struct type是否以与.Equals
的适当重载等效的方式重载运算符=
(可能是.Equals(object))
被汽车覆盖
或刚刚被系统覆盖。ValueType
,或可能是。等于(汽车)
(如果宣布超载)。