c#如何找到两个对象是否相等

我需要知道比较两个对象的最佳方法,并找出是否相同。 我正在重写GethashCode和Equals。 所以一个基本类看起来像:

public class Test { public int Value { get; set; } public string String1 { get; set; } public string String2 { get; set; } public override int GetHashCode() { return Value ^ String1.GetHashCode() ^ String2.GetHashCode(); } public override bool Equals( object obj ) { return GetHashCode() == obj.GetHashCode(); } } 

所以出于测试目的,我创建了两个对象:

 Test t = new Test() { Value = 1, String1 ="One", String2 = "One" }; Test t2 = new Test() { Value = 1, String1 = "Two", String2 = "Two" }; bool areEqual = t.Equals( t2 ); 

在测试中,这两个对象不同,所以areEqual返回true事件。 我意识到这是因为String1和String2在每个对象中是相同的值,因此在散列时相互抵消。

是否有一个更好的方法可以解决哈希对象,我的方法将解决我的问题?

您当前的等式方法已被破坏 – 值可能超过可能的哈希码。 你偶尔会得到不相等的值但是给出相同的哈希是完全合理的(并且是预期的)。 等于应检查实际值

 public override bool Equals(object obj) { Test test = obj as Test; if (obj == null) { return false; } return Value == test.Value && String1 == test.String1 && String2 == test.String2; } 

有几点需要注意:

  • 如果String1String1相同,那么生成哈希码的方法将为任何固定Value提供相同的值; 如果String1String1为null,它也会爆炸。 这是使用XOR进行散列的一个不幸的方面。 我更喜欢这样的东西:

     // Put this extension method in a utility class somewhere public static int SafeGetHashCode(this T value) where T : class { return value == null ? 0 : value.GetHashCode(); } // and this in your actual class public override int GetHashCode() { int hash = 19; hash = hash * 31 + Value; hash = hash * 31 + String1.SafeGetHashCode(); hash = hash * 31 + String2.SafeGetHashCode(); return hash; } 
  • 一般来说,当涉及inheritance时,平等变得棘手。 你可能想考虑密封你的课程。

  • 您可能还想实现IEquatable

你的Equals不正确 – 应该定义两个相等的东西 – 并且具有相同的散列码并不意味着相等(然而,不同的散列码意味着不相等)。 如果“相等”意味着“两个字符串成对相等”,那么测试一下。

更好的哈希; xor因此而臭名昭着,因为通过xor得到0与自身的值是微不足道的。 更好的方法可能是这样的:

 int i = 0x65407627; i = (i * -1521134295) + Value.GetHashCode(); i = (i * -1521134295) + (String1 == null ? 0 : String1.GetHashCode()); i = (i * -1521134295) + (String2 == null ? 0 : String2.GetHashCode()); return i; 

简单

 Object.Equals(obj1, obj2); 

对于任何两个对象,对象相等性意味着哈希代码相等, 但是 ,哈希代码相等并不意味着对象相等。 来自MSDN上的Object.GetHashCode

哈希函数必须具有以下属性:

如果两个对象比较相等,则每个对象的GetHashCode方法必须返回相同的值。 但是,如果两个对象的比较不相等,则两个对象的GetHashCode方法不必返回不同的值。

换句话说,你的Equals写错了。 它应该是这样的:

 public override bool Equals(object obj) { Test other = obj as Test; if (other == null) return false; return (Value == other.Value) && (String1 == other.String1) && (String2 == other.String2); } 

GetHashCode适用于集合(如Dictionary )以快速确定近似相等性。 Equals用于比较两个对象是否真的相同。

您可以将两个对象序列化为JSON,然后比较两个字符串以查看它们是否相同。

例如

 JavaSriptSerializer serialiser = new JavaScriptSerializer(); string t1String = serialiser.Serialize(t); string t2String = serialiser.Serialize(t2); if(t1String == t2String) return true; //they are equal else return false; 

不会是一个函数Equals总是只测试相同的类型,不应该是:

 //override public bool Equals(Test other)//(object obj) { //return GetHashCode() == obj.GetHashCode(); return (Value == other.Value) && (String1 == other.String1) && (String2 == other.String2); } 

关于哎呀