遵守的原则:
1. equals相等则hashcode必须相等
2. hashcode相等equals不一定相等
3. 哈希表的key尽量使用简单类型,否则的话怎么构造一个有效的hash函数会是一个大问题
其他自定义的类一般怎么重写virtual gethashcode
1. return string1.GetHashCode()^string2.GetHashCode()
2. 这种方式非常奇怪,因为这样会导致同一类型的hashcode都相同
也许它压根就不想成为
type=GetType(); return type.GetHashCode();
本质上是调用了Type类中gethashcode,本质上type又是调用的实现类RuntimeType
3. 也许默认直接调用父类Object的就可以了
复杂的是Single,Double,Decimal,String这些
0. Object
return RuntimeHelpers.GetHashCode(this);
public static extern int GetHashCode(Object o);
1. Single
float f = m_value;
if (f == 0)
{
// Ensure that 0 and -0 have the same hash code
return 0;
}
int v = *(int*)(&f);
return v;
2. Double
double d = m_value;
if (d == 0)
{
// Ensure that 0 and -0 have the same hash code
return 0;
}
long value = *(long*)(&d);
return unchecked((int)value) ^ ((int)(value >> 32));
3. Decimal
public extern override int GetHashCode();
4. String
太复杂
基元类型中一般返回值,有三个修改了gethashcode
1. sbyte
public override int GetHashCode() {
return ((int)m_value ^ (int)m_value << 8);
}
2. short 和char是一样的
public override int GetHashCode() {
return ((int)((ushort)m_value) | (((int)m_value) << 16));
}
3. char 和short一样
public override int GetHashCode()
{
return (int)m_value | ((int)m_value << 16);
}
测试代码
List<ListValue> list = new List<ListValue>(13);
list.Add(new ListValue { type = "byte", value = (byte)1 });
list.Add(new ListValue { type = "sbyte", value = (sbyte)2 });
list.Add(new ListValue { type = "ushort", value = (ushort)3 });
list.Add(new ListValue { type = "short", value = (short)4 });
list.Add(new ListValue { type = "char", value = (char)'a' });
list.Add(new ListValue { type = "Int32", value = (Int32)6 });
list.Add(new ListValue { type = "UInt32", value = (UInt32)7 });
list.Add(new ListValue { type = "Int64", value = (Int64)8 });
list.Add(new ListValue { type = "UInt64", value = (UInt64)9 });
list.Add(new ListValue { type = "Single", value = (Single)10 });
list.Add(new ListValue { type = "Double", value = (Double)11 });
list.Add(new ListValue { type = "Decimal", value = (Decimal)12 });
list.Add(new ListValue { type = "string", value = "abcdef" });
foreach (ListValue item in list)
{
Console.WriteLine($"{item.type}-{item.value}-{item.value.GetHashCode()}");
}
结果
byte-1-1
sbyte-2-514 //修改
ushort-3-3
short-4-262148 //修改
char-a-6357089 //修改
Int32-6-6
UInt32-7-7
Int64-8-8
UInt64-9-9
Single-10-1092616192
Double-11-1076232192
Decimal-12-1076363264
abcdef-abcdef-392335469