在Equals()中检查null

时间:2014-09-29 09:21:47

标签: c#

如果我在覆盖Equals()时注释掉第二行怎么样:

public override bool Equals(object obj) {
    if(object.ReferenceEquals(this, obj)) return true;
    //if(obj == null) return false;
    Person other = obj as Person;
    if(other == null) return false;
    return this.Name == other.Name;
}

我收到NullReferenceException?如果我取消注释它,它将起作用。此外,我确保obj参数不是null,它仍然可以。

这是完整的代码

namespace MyNameSpace{

class Person : IComparable<Person>{
    public string Name { get; set; }

    public Person(string name) {
        Name = name;
    }
    public static bool operator <(Person x, Person y) {
        return x.CompareTo(y) < 0;
    }
    public static bool operator >(Person x, Person y) {
        return x.CompareTo(y) > 0;
    }
    public static bool operator ==(Person x, Person y) {
        return x.Equals(y);
    }
    public static bool operator !=(Person x, Person y) {
        return !x.Equals(y);
    }
    public override bool Equals(object obj) {
        if(object.ReferenceEquals(this, obj)) return true;
        //if(obj == null) return false;
        Person other = obj as Person;
        if(other == null) return false;
        return this.Name == other.Name;
    }
    public int CompareTo(Person other) {
        return this.Name.CompareTo(other.Name);
    }
}

class Program {
    static void Main(string[] args) {

        Person one = new Person("one");
        Person two = new Person("two");

        Console.WriteLine(one == two);
    }
}

}

3 个答案:

答案 0 :(得分:2)

我怀疑您在==上有一个自定义Person运算符,该行正在被该行调用:

if(other == null) return false;

这也提示操作员有错误并且应该修复。

修改:以及您的更新:此处 错误的自定义==运营商:

public static bool operator ==(Person x, Person y) {
    return x.Equals(y);
}

只使用:

public static bool operator ==(Person x, Person y) {
    return Equals(x,y);
}        

将解决这个问题,同时:

public override bool Equals(object obj) {
    if(obj == (object)this) return true; // ref equality, the cheap way
    if(obj is Person) {
        Person other = (Person)obj;
        return this.Name == other.Name;
    }
    return false;
}

答案 1 :(得分:1)

作为IComparable实施的一般规则,我强烈推荐Eric Lippert's approach。它非常简单,并且很难获得NRE。

基本上,在任何运算符重载中都不会调用Equals==。您只需调用一个完成所有工作的唯一静态方法:

public int CompareTo(Natural x) { return CompareTo(this, x); }
public static bool operator <(Natural x, Natural y) { return CompareTo(x, y) < 0; }
public static bool operator >(Natural x, Natural y) { return CompareTo(x, y) > 0; }
public static bool operator <=(Natural x, Natural y) { return CompareTo(x, y) <= 0; }
public static bool operator >=(Natural x, Natural y) { return CompareTo(x, y) >= 0; }
public static bool operator ==(Natural x, Natural y) { return CompareTo(x, y) == 0; }
public static bool operator !=(Natural x, Natural y) { return CompareTo(x, y) != 0; } 
public override bool Equals(object obj) { return CompareTo(this, obj as Natural) == 0; }
public bool Equals(Natural x) { return CompareTo(this, x) == 0; }

// negative means x < y 
// positive means x > y 
// zero means x == y 
// two nulls are equal 
// otherwise, null is always smaller 
private static int CompareTo(Natural x, Natural y) { 
    if (ReferenceEquals(x, y)) 
        return 0; 
    else if (ReferenceEquals(x, null)) 
        return -1; 
    else if (ReferenceEquals(y, null)) 
        return 1; 
    else if (ReferenceEquals(x, Zero)) 
        return -1; 
    else if (ReferenceEquals(y, Zero)) 
        return 1; 
    else if (x.head == y.head) 
        return CompareTo(x.tail, y.tail); 
    else if (x.head == ZeroBit) 
        return CompareTo(x.tail, y.tail) > 0 ? 1 : -1; 
    else 
        return CompareTo(x.tail, y.tail) < 0 ? -1 : 1; 
}

答案 2 :(得分:0)

我明白了,我递归地调用了operator ==,并且在某些时候我有operator ==(x,y),其中x和y都是null,然后我做了x.Equals(),那&# 39;为什么它抛出了那个例外。