lan*_*der 30 c# hash comparison
我需要知道比较两个对象的最佳方法,并找出是否相等.我正在重写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();
}
}
Run Code Online (Sandbox Code Playgroud)
所以出于测试目的,我创建了两个对象:
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 );
Run Code Online (Sandbox Code Playgroud)
在测试中,这两个对象不同,所以areEqual返回true事件.我意识到这是因为String1和String2在每个对象中都是相同的值,因此在散列时会相互抵消.
是否有一个更好的方法可以解决哈希对象,我所拥有的方法可以解决我的问题?
Jon*_*eet 40
您当前的相等方法已被破坏 - 值可能超过可能的哈希码.你偶尔会得到不相等的值但是给出相同的哈希是完全合理的(并且是预期的).等于应检查实际值:
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;
}
Run Code Online (Sandbox Code Playgroud)
有几点需要注意:
您生成哈希码的方式将为任何固定的Valueif 提供相同的值,String1并且String2是相同的; 如果String1或String2为空,它也会爆炸.这是使用XOR进行散列的一个不幸的方面.我更喜欢这样的东西:
// 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;
}
Run Code Online (Sandbox Code Playgroud)一般来说,当涉及继承时,平等变得棘手.你可能想考虑密封你的课程.
您可能还想实施 IEquatable<Test>
Mar*_*ell 16
你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;
Run Code Online (Sandbox Code Playgroud)
小智 5
简单
Object.Equals(obj1, obj2);
Run Code Online (Sandbox Code Playgroud)