在.NET GetHashCode方法中,很多地方都使用.NET 方法.特别是在快速查找集合中的项目或确定相等性时.是否有关于如何GetHashCode为我的自定义类实现覆盖的标准算法/最佳实践,因此我不会降低性能?
有没有办法获取实例的唯一标识符?
GetHashCode()对于指向同一实例的两个引用是相同的.但是,两个不同的实例可以(很容易)获得相同的哈希码:
Hashtable hashCodesSeen = new Hashtable();
LinkedList<object> l = new LinkedList<object>();
int n = 0;
while (true)
{
object o = new object();
// Remember objects so that they don't get collected.
// This does not make any difference though :(
l.AddFirst(o);
int hashCode = o.GetHashCode();
n++;
if (hashCodesSeen.ContainsKey(hashCode))
{
// Same hashCode seen twice for DIFFERENT objects (n is as low as 5322).
Console.WriteLine("Hashcode seen twice: " + n + " (" + hashCode + ")");
break; …Run Code Online (Sandbox Code Playgroud) 在本文中,Jon Skeet提到他通常使用这种算法来覆盖GetHashCode().
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + Id.GetHashCode();
return hash;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我尝试使用它,但Resharper告诉我,方法GetHashCode()应该只使用只读字段进行散列(尽管编译很好).什么是好的做法,因为现在我真的不能让我的字段是只读的?
我尝试通过Resharper生成这个方法,这是结果.
public override int GetHashCode()
{
return base.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
这没什么贡献,说实话......
据我所知,GetHashCode将为两个共享相同值的不同实例返回相同的值.在这一点上,MSDN文档有点模糊.
哈希码是一个数值,用于在相等测试期间标识对象.
如果我有两个相同类型和相同值的实例,GetHashCode()将返回相同的值?
假设所有值都相同,以下测试会过去还是失败?
SecurityUser只有getter和setter;
[TestMethod]
public void GetHashCode_Equal_Test()
{
SecurityUser objA = new SecurityUser(EmployeeName, EmployeeNumber, LastLogOnDate, Status, UserName);
SecurityUser objB = new SecurityUser(EmployeeName, EmployeeNumber, LastLogOnDate, Status, UserName);
int hashcodeA = objA.GetHashCode();
int hashcodeB = objB.GetHashCode();
Assert.AreEqual<int>(hashcodeA, hashcodeB);
}
/// <summary>
/// This class represents a SecurityUser entity in AppSecurity.
/// </summary>
public sealed class SecurityUser
{
#region [Constructor]
/// <summary>
/// Initializes a new instance of the <see cref="SecurityUser"/> class using the
/// parameters passed.
/// </summary>
/// <param …Run Code Online (Sandbox Code Playgroud)