当此== null且o​​bj == null时调用IEquatable <t> .Equals(T obj)的结果?</t>

时间:2011-11-11 13:54:04

标签: c# .net f# equals equality

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时没有定义方法的行为。

7 个答案:

答案 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()。

相关问题