CSharp - C# 如何查找两个对象是否相等

我需要知道比较两个对象的最佳方法,并找出是否相等,基本类如下所示:


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 );

时间:

您当前的判断相等方法是没用的 - 值比哈希码更多。


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;
}

需要注意的一些事项:

  • 如果String1和String2相同,则用生成哈希码的方式为任何固定值提供相同的值;如果String1String2为null,它也会放大,我更喜欢这样的东西:

    
    // Put this extension method in a utility class somewhere
    public static int SafeGetHashCode<T>(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;
    }
    
    
  • 一般来说,当涉及继承时,相等会变得棘手。

  • 你可能还想实现IEquatable<Test>

更好的方法可能是:


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;

除了所有的答案我建议你阅读本文 Alois克劳斯

(MSDN)

简单


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);
}

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;


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

...