调用equable 的结果.当this == null且obj == null时,等于(T obj)

本文关键字:obj null 等于 this equable 结果 调用 | 更新日期: 2023-09-27 18:14:06

this == nullobj == null出现时,IEquatable<T>.Equals(T obj)应该怎么做?

1)此代码由f#编译器在实现IEquatable<T>时生成。您可以看到,当两个对象都是null时,它返回true:

<>之前public密封覆盖bool等于(T对象){If (this == null){返回obj == null;}If (obj == null){返回错误;}//this和obj都不为空时的代码。}之前

2)类似的代码可以在问题"在等价实现中是否需要引用检查"或问题"是否有完整的等价实现参考?"中找到。当两个对象都是null时,此代码返回false

<>之前public密封覆盖bool等于(T对象){If (obj == null){返回错误;}//obj不为空时的代码。}之前

3)最后一个选项是说当this == null .

调用equable <T>的结果.当this == null且obj == null时,等于(T obj)

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()时获得运行时异常。