C#中类对象的Equals方法疑问:为何初始化值相同的对象不相等?
为什么两个
i值相同的类A对象调用Equals会返回false? 嘿,这个问题其实是C#引用类型默认相等性判断的典型场景,我来给你掰扯清楚~
首先要明确:类是引用类型,在默认情况下,Equals方法(包括==运算符,不过你这里用的是Equals)判断的是引用相等性——简单说就是看两个变量是不是指向内存堆里的同一个对象实例,而不是比较对象内部的字段值。
看你的代码:
A a = new A(); // 创建第一个独立对象 A b = new A();// 创建第二个独立对象
这两行代码分别在内存里创建了两个完全分开的A实例,它们的内存地址不一样,哪怕i的值都是10,a.Equals(b)也会认为这两个对象不相等,因为它们根本不是同一个东西。
怎么让它按字段值判断相等?
如果你想让两个A对象根据i的值来判定相等,就需要重写Equals方法,同时记得重写GetHashCode(这是.NET的约定,因为哈希表这类集合会依赖GetHashCode,如果只重写Equals不重写GetHashCode会导致奇怪的问题)。
给你个示例代码:
class A { public int i; public A() { i = 10; } // 重写Equals方法 public override bool Equals(object obj) { // 如果是同一个引用直接返回true if (ReferenceEquals(this, obj)) return true; // 如果obj是null或者类型不对,返回false if (obj is null || GetType() != obj.GetType()) return false; // 转换类型后比较字段值 A otherObj = (A)obj; return i == otherObj.i; } // 必须配套重写GetHashCode public override int GetHashCode() { // 用i的哈希值作为当前对象的哈希值 return i.GetHashCode(); } }
或者更规范一点,实现IEquatable<A>接口,这样可以避免不必要的类型转换,让代码更安全:
class A : IEquatable<A> { public int i; public A() { i = 10; } // 类型安全的Equals方法 public bool Equals(A other) { if (other is null) return false; return i == other.i; } // 重写object的Equals,调用上面的类型安全版本 public override bool Equals(object obj) { return Equals(obj as A); } public override int GetHashCode() { return i.GetHashCode(); } }
修改之后再运行代码,a.Equals(b)就会返回true,输出"Both objects are equal "啦~
内容的提问来源于stack exchange,提问作者mahi batra
相关产品推荐
相关产品推荐

