调用equable 的结果.当this == null且obj == null时,等于(T obj)
本文关键字:obj null 等于 this equable 结果 调用 | 更新日期: 2023-09-27 18:14:06
当this == null
和obj == null
出现时,IEquatable<T>.Equals(T obj)
应该怎么做?
1)此代码由f#编译器在实现IEquatable<T>
时生成。您可以看到,当两个对象都是null
时,它返回true
:
2)类似的代码可以在问题"在等价实现中是否需要引用检查"或问题"是否有完整的等价实现参考?"中找到。当两个对象都是null
时,此代码返回false
。
3)最后一个选项是说当this == null
.
leppie是对的。只是为了详细说明他的答案(并确认他怀疑f#不能保证this != null)
:可以用属性[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
标记有区别的联合,允许用值null表示情况)。Option<'T>
就是这样一种类型。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
f#这样做的原因(我怀疑)是将空列表优化为null
。
通过添加这个检查,它允许在null
实例上调用实例方法而没有任何问题。
查看我之前的博客。
在c#中,这是无关的。
回答问题:
它应该返回true
,因为两个实例都是null
并且被认为是相等的。
如果this
是空的,代码不能被调用,所以不需要考虑这种情况(无论如何,在c#中,有些情况下,语言允许null对象具有解引用的方法,但显然,如果它在内部检查任何不存在的字段,它将会出错。考虑:
return x.Equals(y);
如果x是null,我们甚至不能调用Equals
来计数null检查。
因此我们只需要考虑:
public bool Equals(T obj)
{
if(obj == null)
return false;
//logic defining equality here.
}
当我们从静态==
操作符覆盖或IEqualityComparer<T>
实现检查它们时,两个对象都为null的可能性确实出现了:
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.
}
对于大多数方法,我假设使用this==null
调用时未定义行为。这是因为大多数程序员在this!=null
的假设下编写他们的代码,如果调用代码是用c#编写的,这是由c#规范保证的。
这就是为什么x.Equals(y)
的每个理智的调用者都应该知道x
不是null
,或者添加一个手动的null
检查。
在大多数情况下,我不会直接调用Equals
,而是使用EqualityComparer<T>.Default
。
我肯定会选择选项1:
if (this == null)
{
return obj == null;
}
if (obj == null)
{
return false;
}
null对象总是等于null对象
示例代码位于MSDN: http://msdn.microsoft.com/en-us/library/ms131190.aspx?ppud=4
如果this==null,您将在该对象上调用Equals()时获得运行时异常。