默认实现如何GetHashCode()工作?它是否有效且足够好地处理结构,类,数组等?
我试图决定在什么情况下我应该自己打包,在什么情况下我可以安全地依赖默认实现来做好.如果可能的话,我不想重新发明轮子.
我在C#中有一个结构:
public struct UserInfo
{
public string str1
{
get;
set;
}
public string str2
{
get;
set;
}
}
Run Code Online (Sandbox Code Playgroud)
唯一的规则是 UserInfo(str1="AA", str2="BB").Equals(UserInfo(str1="BB", str2="AA"))
如何覆盖此结构的GetHashCode函数?
我在StackOverflow上阅读了大部分关于的问题GetHashCode.但我仍然不确定是否必须覆盖GetHashCode引用类型.我从另一个问题的某些人那里得到了以下答案:
Object.GetHashCode()使用System.Object类中的内部字段来生成哈希值.创建时,为每个创建的对象分配一个唯一的对象键,存储为整数.这些键从1开始,每次创建任何类型的新对象时都会递增.
如果在.NET Framework 3.5中仍然如此(有人可以确认吗?),那么我在参考类型的默认实现中看到的唯一问题是哈希代码的分布很差.
我会打破我的问题:
a)所以建议覆盖GetHashCode它是否在a中使用Dictionary或者默认实现是否正常?
b)我有很容易做的引用类型,因为它们具有唯一标识它们的字段,但是那些所有成员也是引用类型的引用类型呢.我该怎么办?
我有一个方法,使用递归遍历树并更新项目.
目前该方法处理所有项目需要很长时间,所以我开始优化.其中包括使用字典而不是为每个项目执行数据库查询.
字典定义为
System.Collections.Generic.Dictionary<EffectivePermissionKey, MyData>
Run Code Online (Sandbox Code Playgroud)
密钥类型定义为
private struct EffectivePermissionKey
{
// http://blog.martindoms.com/2011/01/03/c-tip-override-equals-on-value-types-for-better-performance/
public override bool Equals(object aObject)
{
if (aObject == null)
return false;
else
return aObject is EffectivePermissionKey && Equals((EffectivePermissionKey)aObject);
}
public bool Equals(EffectivePermissionKey aObject)
{
return this.ID == aObject.ID && this.OrchardUserID == aObject.OrchardUserID;
}
public override int GetHashCode()
{
// http://stackoverflow.com/a/32502294/3936440
return unchecked(ID.GetHashCode() * 23 * 23 + OrchardUserID.GetHashCode() * 23);
}
public int ID;
public int OrchardUserID;
}
Run Code Online (Sandbox Code Playgroud)
该方法运行时,需要大约5000次递归才能更新所有项目.
最初没有字典需要大约100秒.
使用带有int键的字典替换数据库查询的第一种方法需要22秒 …