如何检查对象是否等于同一类的新对象?

如果我有一个像这样的对象:

public class Person { public int id {get;set;} public string name {get;set;} } 

我想要的行为:

 Person a = new Person(); Person b = new Person(); a == b; 

并且a == b返回true,我是否必须覆盖Object.Equals()方法? 或者是否有其他方法可以不覆盖Equals方法?

编辑

我想比较数据,因为我想知道我调用的外部方法是否返回一个新对象或一个具有不同于新对象的数据的对象

有几种方法可以做到这一点。 默认情况下, Equals()==检查引用相等性,意思是:

 Person a = new Person(); Person b = a: a.Equals(b); //true a == b; //true 

因此,不会将对象与值相等进行比较,这意味着:

 Person a = new Person { id = 1, name = "person1" }; Person b = new Person { id = 1, name = "person1" }; a.Equals(b); //false a == b; //false 

要比较对象的值,可以覆盖Equals()GetHashcode()方法,如下所示:

 public override bool Equals(System.Object obj) { if (obj == null) return false; Person p = obj as Person; if ((System.Object)p == null) return false; return (id == p.id) && (name == p.name); } public bool Equals(Person p) { if ((object)p == null) return false; return (id == p.id) && (name == p.name); } public override int GetHashCode() { return id.GetHashCode() ^ name.GetHashCode(); } 

现在,您将在比较时看到其他结果:

 Person a = new Person { id = 1, name = "person1" }; Person b = new Person { id = 1, name = "person1" }; Person c = a; a == b; //false a == c; //true a.Equals(b); //true a.Equals(c); //true 

==运算符不会被覆盖,因此仍然会进行参考比较。 这可以通过重载它以及!=运算符来解决:

 public static bool operator ==(Person a, Person b) { if (System.Object.ReferenceEquals(a, b)) return true; if ((object)a == null || (object)b == null) return false; return a.id == b.id && a.name == b.name; } public static bool operator !=(Person a, Person b) { return !(a == b); } 

现在运行检查结果如下:

 Person a = new Person { id = 1, name = "person1" }; Person b = new Person { id = 1, name = "person1" }; Person c = a; a == b; //true a == c; //true a.Equals(b); //true a.Equals(c); //true 

更多阅读:

  • 实施平等和平等操作员指南(==)

这一切都取决于您要比较的内容,默认情况下, Equals将通过引用进行比较

 a == b 

在你的例子中将永远是false 。 但是,如果你做了类似的事情

 Person a = new Person(); Person b = a; 

然后a == b将为true因为ab都使用相同的引用

我必须覆盖Object.Equals()方法吗?

但是,重写Equals和GetHashCode是推荐的方法(为了论证),这不是唯一的方法。 例如,您可以覆盖==运算符并在那里进行比较。 但是,单独沿着那条路走下去就有局限性。

大多数比较检查,如果不是全部,将在内部使用Equals ,这就是为什么它是首选方法。 参见实现等于和等式运算符的指南(==) 。

您想要重载==运算符。 因此,您还应首先覆盖Equals 。 如果重写Equals ,则应始终覆盖GetHashCode 。 如果重载==运算符,则还必须重载!=运算符:

 public class Person { public int id {get;set;} public string name {get;set;} public override bool Equals(object obj) { Person p2 = obj as Person; if (object.ReferenceEquals(null, p2)) return false; return id == p2.id; } public static bool operator ==(Person p1, Person p2) { if (object.ReferenceEquals(null, p1)) return object.ReferenceEquals(null, p2); else if (object.ReferenceEquals(null, p2)) return false; return p1.Equals(p2); } public static bool operator !=(Person p1, Person p2) { if (object.ReferenceEquals(null, p1)) return !object.ReferenceEquals(null, p2); else if (object.ReferenceEquals(null, p2)) return true; return !p1.Equals(p2); } public override int GetHashCode() { return id ; } } 

现在,这将比较值( id )而不仅仅是引用:

 Person p1 = new Person { id = 1, name = "Jeff" }; Person p2 = new Person { id = 2, name = "Tim" }; bool equalPersons = p1 == p2; // false Person p3 = new Person { id = 1, name = "Jeff 2.0" }; // same id -> equal equalPersons = p1 == p3; // true 

MSDN:实现等于和平等运算符的指南(==)

假设测试是Class

 Test a = new Test() { Num = 1, Str = "Hi" }; Test b = new Test() { Num = 1, Str = "Hi" }; bool areEqual = System.Object.ReferenceEquals(a, b); 

是。 您想要与Person的对象进行比较,您需要从Object类重写equals和hashcode方法,因为默认情况下,引用check(==)是通过equals方法完成的。

假设具有相同名称和id的两个人只能被视为相等,则在equals和hashcode方法中使用这两个属性。

使用Java IDE提供的生成equals和hashcode更容易。 你可以尝试下面的代码。

 public class Person { private int id; private String name; // id getters and setters // name getters and setters @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (id != other.id) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } } 
 object.Equals(object2); 

在你的情况下:

 a.Equals(b);