【问题标题】:Is it ever acceptable to return True when the parameter to Equals is a null reference?当 Equals 的参数是空引用时,返回 True 是否可以接受?
【发布时间】:2009-10-07 23:31:40
【问题描述】:

Object.Equals 的文档说,如果参数是空引用,实现者必须返回 false。

在我的课堂上,我将覆盖 Equals 以检查值是否相等。我有一个类似于Nullable (T) 结构的成员变量。当我传递一个空引用并且我的结构的 HasValue 属性为 False 时,我最初的倾向是返回 True。

当 Equals 的参数是空引用时返回 True 是否可以接受?

编辑 举例说明:

class ExampleClass {

    SomeValueType? x;

    bool Equals(object other) {
        if (other == null) return false; // <-- returns a different value than x.Equals
        return x.Equals(other); 
    }
}

【问题讨论】:

  • null==null 吗?这是一个正确的哲学罐头。
  • @spender: 当thisnull 且代码null==null 中的文字为真时,永远无法调用Object.Equals,因此这一点没有实际意义。
  • 啊。这只是为了方便。我仍然在脑海中与它作斗争。
  • 默认操作符 == 调用 Object.Equals(Object a,Object b),返回 (Object.ReferenceEquals(a,null) ? Object.ReferenceEquals(b,null) : a.Equals(b))

标签: c# .net


【解决方案1】:

Nullable&lt;T&gt;.Equals(object) 如下:

public override bool Equals(object other)
{
    if (!this.HasValue)
    {
        return (other == null);
    }
    if (other == null)
    {
        return false;
    }
    return this.value.Equals(other);
}

因此,对于具有可为空语义的struct(值类型),您的问题的答案是肯定的。如果你的类型是class(引用类型),答案肯定是no

【讨论】:

  • 好吧,我的班级正在遵循我的结构的Equals。在空引用的特殊情况下它不会延迟似乎不直观
  • 从我现在掌握的有限信息(包括您的示例)来看,您的设计似乎不直观。我认为对于引用类型,Equals 应该总是obj==null 时返回false。你到底想在这里做什么?为什么不将x 改为SomeValueType 而不是SomeValueType?
  • 它是 Nullable(T) 的包装器,它允许继承者实现 TryParseValueFromString 方法。
  • 我想我不明白为什么你不能 1) 因为它显然是一个日期,所以将对象公开为DateTimeOffset(不可为空)或DateTimeOffset?(可空)或2) 公开由DateTimeOffset/DateTimeOffset? 私有成员支持的string 属性,并在值不是null 时在getter 中调用ToString,在setter 中调用Parse
  • 我现在明白了。谢谢你的帮助。我不会将我的结构存储在我的“智能”类中。
【解决方案2】:

其实不是。当两个对象为空时,equals方法不能返回true。

为什么?

当你定义的时候

AnObject obj;

obj 是对对象的引用(我说的是 Java,但这必须是一个 OO 概念)

Object.Equals 方法接受一个参数,该参数必须是一个对象,但 null 不是一个对象。

所以 null.Equals(null) 不是 OO 可接受的方法。

编辑:

这就是 == 运算符与 obj.Equals 方法不同的原因。 null == null 返回 true 不会让人头疼。

Edit2:.Net 似乎与 Equals 方法不一致,可能会受到另一个主题的影响。

int? a = null;
a.Equals(null); // returns true without any problem.

但是:

Nullable&lt;T&gt;.Equals 方法定义如下:

Nullable<T>.Equals(object obj):bool

表示当前是否 可空值等于 a 指定的对象

由于 null 不是对象,因此文档或实现都不正确。

【讨论】:

  • 更具体地说,这是静态方法Object.Equals(Object,Object)和虚拟成员方法Object.Equals(Object)的区别。您的回答没有说​​明根据标准 (ECMA-335),只要 HasValue 为假,特殊值类型 Nullable&lt;T&gt; 就会框到 null
  • @jcasso:标准 ECMA-335 专门为值类型 System.Nullable&lt;T&gt; 提供了特殊语义,当 HasValuefalse 时,它会框到对象引用 null。唯一的其他选择是使 Nullable&lt;T&gt; 成为实际上可以设置为 null 引用的引用类型,但这会对性能产生重大(负面)影响,因为它实际上与装箱/拆箱相同基础类型。
  • @280Z28 似乎 Nullable.equals(object) 方法在这里做了不同的工作。它覆盖 System.Object.Equals 方法。如果 HasValue 属性为 false,则不会抛出异常......正如我上面提到的,我在谈论 Java,但我们在这里谈论的不仅仅是一种语言,它是关于面向对象的编程。对我来说,我仍然坚持认为这是一种非常糟糕的方法。 Equals 方法必须与对象进行比较,而不是对象的引用。
  • 还有“如果一个对象没有值,它可能等于或不等于一个对象”算法?恭喜发明者。
猜你喜欢
  • 2014-12-19
  • 1970-01-01
  • 1970-01-01
  • 2012-10-03
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多