当 this == null
和 obj == null
时, IEquatable<T>.Equals(T obj)
应该怎么做?
1) 实现 IEquatable<T>
时,此代码由F#编译器生成 . 当两个对象都是 null
时,您可以看到它返回 true
:
public sealed override bool Equals(T obj)
{
if (this == null)
{
return obj == null;
}
if (obj == null)
{
return false;
}
// Code when both this and obj are not null.
}
2) 类似代码可在“in IEquatable implementation is reference check necessary " or in the question " Is there a complete IEquatable implementation reference?”问题中找到 . 当两个对象都是 null
时,此代码返回 false
.
public sealed override bool Equals(T obj)
{
if (obj == null)
{
return false;
}
// Code when obj is not null.
}
3) 最后一个选项是说 this == null
时没有定义方法的行为 .
7 回答
F#这样做(我怀疑)将空列表优化为
null
.通过添加此检查,它允许在没有任何问题的情况下在
null
实例上调用实例方法 .不久前见my blog post .
在C#中,这是无关紧要的 .
To answer the question:
它应返回
true
,因为两个实例都是null
并且视为相等 .leppie是对的 . 只是详细说明他的答案(并确认他怀疑F#不保证
this != null)
:有区别的联盟可能会用属性[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
标记,允许案例由值null表示.Option<'T>就是这样的类型.None
案例由在运行时为null .(None : option<int>).Equals(None)
在语法上是有效的 . 这是一个有趣的例子:用Reflector显示反编译
ThisIsNull
结果如下:
如果
this
为null,则代码可以被考虑(无论如何,在C#中,有些情况下语言允许空对象具有解除引用的方法,但显然如果它在内部检查它的任何不存在的字段,它将会出错 . 考虑:如果x为null,我们甚至不会调用
Equals
来进行空检查计数 .因此我们只需要考虑:
如果我们从静态
==
运算符覆盖或IEqualityComparer<T>
实现中检查它们,那么两个对象的可能性确实出现了:注意这里有一个有用的快捷方式,如果相等可以很长时间来确定(例如比较长字符串),那么我们可以利用身份需要平等的事实 - 即使Ayn Rand能够解决这个问题,这个问题总是等于它自己 . )还有一些算法可以使项目与自身进行比较非常普遍,这使得这个快捷方式非常值得包括 . 在这种情况下,身份比较已经包括检查两者都为null,所以我们再次将其保留:
对于大多数方法,我在使用
this==null
调用时假设未定义的行为 . 这是因为大多数程序员在this!=null
的假设下编写代码,如果调用代码是用C#编写的,则由C#规范保证 .这就是为什么
x.Equals(y)
的每个理智的调用者应该确定x
不是null
,或者添加一个手册null
检查 .在大多数情况下,我根本不会直接调用
Equals
,而是使用EqualityComparer<T>.Default
.我肯定会选择1:
null对象始终等于null对象 .
示例代码位于MSDN中:http://msdn.microsoft.com/en-us/library/ms131190.aspx?ppud=4
如果这= = null,您将获得一个在该对象上调用Equals()的运行时异常 .