我的理解是你通常应该使用xor和GetHashCode()生成一个int来通过它的值来识别你的数据(而不是通过它的引用).这是一个简单的例子:
class Foo
{
int m_a;
int m_b;
public int A
{
get { return m_a; }
set { m_a = value; }
}
public int B
{
get { return m_b; }
set { m_b = value; }
}
public Foo(int a, int b)
{
m_a = a;
m_b = b;
}
public override int GetHashCode()
{
return A ^ B;
}
public override bool Equals(object obj)
{
return this.GetHashCode() == obj.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
我的想法是,我想根据属性A和B的值将Foo的一个实例与另一个实例进行比较.如果Foo1.A == Foo2.A和Foo1.B == Foo2.B,那么我们就有了相等性. …
在C#中为类创建自己的GetHashCode方法的最佳方法是什么?假设我有一个简单的类(它覆盖了Equals方法),如下所示:
class Test
{
public string[] names;
public double[] values;
public override bool Equals(object obj)
{
return (obj is Test) && this.Equals((Test)obj);
}
public bool Equals(Test t)
{
return names.Equals(t.names) && values.Equals(t.values);
}
}
Run Code Online (Sandbox Code Playgroud)
我应该使用GetHashCode方法的默认代码吗?
public override int GetHashCode()
{
return base.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
我应该将该方法基于我班级的内容吗?
public override int GetHashCode()
{
return names.GetHashCode() + values.GetHashCode() ;
}
Run Code Online (Sandbox Code Playgroud)
或者我应该做些什么?
我有一个方法,使用递归遍历树并更新项目.
目前该方法处理所有项目需要很长时间,所以我开始优化.其中包括使用字典而不是为每个项目执行数据库查询.
字典定义为
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秒 …
我决定在我们的一个应用程序中实现缓存外观 - 目的是最终减少网络开销并限制db命中量.我们正在使用Castle.Windsor我们IoC Container,我们决定Interceptors使用System.Runtime.Caching命名空间在我们的服务层之上添加缓存功能.
在这一刻,我无法弄清楚什么是构建它的最佳方法cache key.目标是区分不同的方法,并且还包括传递的参数值 - 这意味着这两个方法调用应该缓存在两个不同的键下:
IEnumerable<MyObject> GetMyObjectByParam(56); // key1
IEnumerable<MyObject> GetMyObjectByParam(23); // key2
Run Code Online (Sandbox Code Playgroud)
现在我可以看到两种可能的实现:
选项1: 装配| 班级| 方法返回类型| 方法名称| 参数类型| 参数哈希码
"MyAssembly.MyClass IEnumerable<MyObject> GetMyObjectByParam(long) { 56 }";
Run Code Online (Sandbox Code Playgroud)
选项2: MD5或SHA-256基于方法的完全限定名称和传递的参数值计算散列
string key = new SHA256Managed().ComputeHash(name + args).ToString();
Run Code Online (Sandbox Code Playgroud)
我正在考虑第一个选项,因为第二个选项需要更多的处理时间 - 另一方面,第二个选项强制执行所有生成的键的完全相同的"长度".
假设第一个选项将为使用复杂参数类型的方法生成唯一键是否安全?或者也许有一种完全不同的做法?
帮助和意见将受到高度赞赏!
数组的最佳哈希方法是byte什么?
这些数组是序列化的类对象,包含通过TCP/IP在应用程序之间传递的jpeg图像.
阵列大小约为200k.
我有两个员工名单,我想从中获得唯一的记录,但这有一个扭曲.每个列表中都有一个Employee类:
public class Employee
{
// I want to completely ignore ID in the comparison
public int ID{ get; set; }
// I want to use FirstName and LastName in comparison
public string FirstName{ get; set; }
public string LastName{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我想要匹配的唯一属性是FirstName和LastName.我想在比较中完全忽略ID.allFulltimeEmployees列表中有3名员工,allParttimeEmployees列表中有3名员工.名单上的两个项目的名字和姓氏相匹配 - 莎莉琼斯和弗雷德杰克逊.列表中有一个项不匹配,因为FirstName是相同的,但LastName不同:
emp.id = null; // not populated or used in comparison
emp.FirstName = "Joe"; // same
emp.LastName = "Smith"; // different
allFulltimeEmployees.Add(emp);
emp.id = 3; // not used in comparison
emp.FirstName = "Joe"; // …Run Code Online (Sandbox Code Playgroud) 我有一个名为'x'的类,它覆盖Equals(),如下所示:
public override bool Equals(object obj)
{
if(obj is x)
{
return ((obj as x).key == this.key);
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
当以下扩展方法尝试使用上面的覆盖进行比较时,不会使用Equals():
public static bool Contains(this HashSet<x> set, char key)
{
x SearchKey = new x(key);
return set.Contains(SearchKey);
}
Run Code Online (Sandbox Code Playgroud)
只有当我修改extensio方法中的第一行时,我才会得到预期的行为,如下所示:
x SearchKey = new x(key);
Run Code Online (Sandbox Code Playgroud)
你能解释一下这种行为吗?
我曾经预料到,Equals()将被调用x本身的实例,因为它是Object的一个子集.我错过了什么?
我正在尝试使用Except方法比较两个列表,但它无法正常工作:
List<Customer> PotentialSharedCustomer = new List<Customer>();
PotentialSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "01234", Name = "Hans Jürgen" });
PotentialSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "05465", Name = "Beate Müller" });
PotentialSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "15645", Name = "Sabine Meyer" });
PotentialSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "54654", Name = "Moritz Kummerfeld" });
PotentialSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "15647", Name = "Hanna Testname" });
List<Customer> ActualSharedCustomer = new …Run Code Online (Sandbox Code Playgroud) 尝试实现一个GetHashCode覆盖类似于Jon的Skeet的建议,在什么是覆盖System.Object.GetHashCode的最佳算法?我注意到在评估顺序中有一些奇怪的行为,当使用条件运算符对类中的集合属性进行空检查时,会导致语法错误.
考虑以下:
public class Foo
{
public String Name { get; private set; }
public List<String> Bar { get; private set; }
public override Int32 GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + this.Name == null ? 0 : this.Name.GetHashCode();
hash = hash * 23 + this.Bar == null ? 0 : this.Bar.GetHashCode();
return hash;
}
}
}
Run Code Online (Sandbox Code Playgroud)
当您收到语法错误时hash = hash * 23 + this.Bar == null ? 0 : this.Bar.GetHashCode(); …
这个问题遵循Jon Skeet在这个问题上给出的答案:" 覆盖System.Object.GetHashCode的最佳算法是什么? ".要计算哈希码,请使用以下算法:
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + field1.GetHashCode();
hash = hash * 23 + field2.GetHashCode();
hash = hash * 23 + field3.GetHashCode();
return hash;
}
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么选择数字17和23.我们为什么不选3和5?这也是素数.有人可以解释一下最好的素数是什么以及为什么?
c# ×10
.net ×4
gethashcode ×3
hash ×3
dictionary ×2
performance ×2
caching ×1
comparison ×1
generics ×1
hashcode ×1
list ×1
primes ×1
recursion ×1