IEquatable<T>.Equals(T obj)
和this == null
时,obj == null
应该做什么?
1)此代码由F#编译器在实现IEquatable<T>
时生成。当两个对象都是true
时,您会看到它返回null
:
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”或问题“Is there a complete IEquatable implementation reference?”中找到。当两个对象都是false
时,此代码返回null
。
public sealed override bool Equals(T obj) { if (obj == null) { return false; } // Code when obj is not null. }
3)最后一个选项是说this == null
时没有定义方法的行为。
答案 0 :(得分:9)
leppie是对的。只是详细说明他的回答(并确认他怀疑F#不保证this != null)
:有区别的联盟可能会标有属性[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
,允许案例用值null表示。{{3}这是一种类型。None
情况在运行时由null表示。(None : option<int>).Equals(None)
在语法上是有效的。这是一个有趣的例子:
[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
type Maybe<'T> =
| Just of 'T
| Nothing
[<CompilationRepresentation(CompilationRepresentationFlags.Instance)>]
member this.ThisIsNull() = match this with Nothing -> true | _ -> false
使用Reflector显示
来反编译ThisIsNull
public bool ThisIsNull()
{
return (this == null);
}
结果:
Nothing.ThisIsNull() //true
答案 1 :(得分:3)
F#这样做(我怀疑)将空列表优化为null
的原因。
通过添加此检查,它允许用户在null
实例上调用实例方法而不会出现任何问题。
不久前见my blog post。
在C#中,这是无关紧要的。
回答这个问题:
它应该返回true
,因为两个实例都是null
并被视为相同。
答案 2 :(得分:1)
如果this
为null,则无法调用代码,因此无需考虑这种情况(无论如何,在C#中,有些情况下语言允许空对象将方法解除引用,但很明显,它在内部检查它将出错的任何不存在的字段。考虑:
return x.Equals(y);
如果x为null,我们甚至无法调用Equals
进行空检查计数。
因此我们只需考虑:
public bool Equals(T obj)
{
if(obj == null)
return false;
//logic defining equality here.
}
当两个对象都为null的可能性出现时,我们是从静态==
运算符覆盖还是从IEqualityComparer<T>
实现检查它们的时候:
public bool Equals(T x, T y)
{
if(x == null)
return y == null;
if(y == null)
return false;
//logic defining equality here.
}
注意这里有一个有用的快捷方式,如果相等可以很长时间来确定(例如比较长字符串),那么我们可以利用身份需要平等的事实 - 即使是Ayn Rand可以想象的东西总是等于它自己那个;)还有一些算法可以比较一个项目与它自己相当普遍,使这个快捷方式值得包括。在这种情况下,身份比较已经包括检查两者都为空,所以我们再次将其留下:
public bool Equals(T x, T y)
{
if(ReferenceEquals(x, y))
return true;
if(x == null || y == null)
return false;
//logic defining equality here.
}
答案 3 :(得分:1)
对于大多数方法,我在使用this==null
调用时假设未定义的行为。这是因为大多数程序员在假设this!=null
的情况下编写代码,如果调用代码是用C#编写的,则由C#规范保证。
这就是x.Equals(y)
每个理智的来电者应该确定x
不是null
,或者添加手动null
支票的原因。
在大多数情况下,我根本不会直接致电Equals
,而是使用EqualityComparer<T>.Default
。
答案 4 :(得分:0)
我决定选择1:
if (this == null)
{
return obj == null;
}
if (obj == null)
{
return false;
}
null对象总是等于null对象。
答案 5 :(得分:0)
答案 6 :(得分:0)
如果这= = null,你将得到一个运行时异常,在该对象上调用Equals()。