我声明了一个C#代码行
int hashcode = "apple".GetHashCode();
Run Code Online (Sandbox Code Playgroud)
在我的计算机,工作中的计算机和朋友的计算机上,结果是1657858284.在开发服务器上,结果是1548091822.有没有办法告诉项目始终使GetHashCode()产生1657858284,无论它在哪个服务器上?
更多说明 首先,我注意到版本有所不同...... 1657858284结果来自.NET 3.5和.NET 4.0.1548091822来自.NET 2.0.
然后我告诉视觉工作室2010将项目编译为.net 2.0项目,但它仍然给了我1657858284.
我正在尝试编写一个方法来根据任何给定的字符串生成一个整数.在2个相同的字符串上调用此方法时,我需要该方法两次生成相同的完整整数.
我尝试使用.GetHasCode()但是当我将项目移动到另一台机器时,这是非常不可靠的,因为GetHasCode()为同一个字符串返回不同的值
碰撞率非常低也很重要.到目前为止我编写的自定义方法仅在几十万个记录之后产生冲突.
哈希值必须是整数.字符串哈希值(如md5)会在速度和负载开销方面削弱我的项目.
整数哈希用于执行非常快速的文本搜索,我工作得很漂亮,但是它当前依赖于.GetHasCode()并且在涉及多台机器时不起作用.
任何见解都将非常感激.
我们应该会覆盖Equals
并GetHashCode
实现自定义的类实例比较时属性?
在下面的代码中,我有一组类.该班A
是由比较ID
,类B
-通过Code
.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
List<I> bars = new List<I>();
bars.Add(new A() { Id = 1, Code = "one A" });
bars.Add(new B() { Id = 1, Code = "one B" });
bars.Add(new A() { Id = 1, Code = "one A+" });
bars.Add(new B() { Id = 1, Code = "one …
Run Code Online (Sandbox Code Playgroud) 对于实现大量的IEqualityComparers有些懒惰,并且考虑到我无法轻松编辑被比较对象的类实现,我使用了以下内容,意味着与Distinct()和Except()扩展方法一起使用.:
public class GenericEqualityComparer<T> : IEqualityComparer<T>
{
Func<T, T, bool> compareFunction;
Func<T, int> hashFunction;
public GenericEqualityComparer(Func<T, T, bool> compareFunction, Func<T, int> hashFunction)
{
this.compareFunction = compareFunction;
this.hashFunction = hashFunction;
}
public bool Equals(T x, T y)
{
return compareFunction(x, y);
}
public int GetHashCode(T obj)
{
return hashFunction(obj);
}
}
Run Code Online (Sandbox Code Playgroud)
看起来不错,但每次真的需要一个哈希函数?我知道哈希码用于将对象放入存储桶中.不同的桶,对象不相等,并且不调用相等.
如果GetHashCode返回相同的值,则调用equals.(来自:为什么在重写Equals方法时重写GetHashCode很重要?)
那么可能出现什么问题,例如(我听到很多程序员惊恐地尖叫),GetHashCode返回一个常量,强制调用Equal?
HashSet<T>.Add
首先比较结果GetHashCode
.如果它们是相同的,它会调用Equals
.
现在,我的理解是为了实现GetHashCode
,必须用对象的字段来完成某些事情.一个简单的示例实现可以在被覆盖的System.Object.GetHashCode的最佳算法是什么?.
在我的测试中,在填充随机数据的1.000.000对对象上进行比较,两者之间的性能或多或少相等.GetHashCode
在链接示例中实现,Equals
只需调用Equals
所有字段.那么为什么要用GetHashCode
它Equals
?
嗨我有一个有6个字符串属性的类.对于这些字段中的至少一个,唯一对象将具有不同的值
为了实现IEqualityComparer的GetHashCode函数,我连接所有6个属性并在结果字符串上调用GetHashCode.
我有以下疑惑:
这个问题有很多问题和答案以及文章,但我认为似乎没有真正明确/正确的答案
对我来说,Ayende迄今为止已经看到了最好的通用实现:http://ayende.com/blog/2500/generic-entity-equality
....但是从2007年开始....
这是实现这些方法的"最佳方式",特别是NHibernate 3.2,它包含代理实现与早期版本的一些差异吗?
给出两个相同的匿名类型对象:
{msg:"hello"} //anonType1
{msg:"hello"} //anonType2
Run Code Online (Sandbox Code Playgroud)
并假设它们没有解析为相同类型(例如,它们可能在不同的程序集中定义)
anonType1.Equals(anonType2); //false
Run Code Online (Sandbox Code Playgroud)
此外,假设在编译时,我无法得到一个(比如说anonType1
)的结构,因为API只暴露object
所以,为了比较它们,我想到了以下技术:
msg
属性以anonType1
进行比较.anonType1
给dynamic
类型和参考.msg
动态构件上用于比较.GetHashCode()
每个对象的结果.我的问题是:使用选项3是否安全?即,假设.GetHashcode()
在.NET框架的当前版本和所有未来版本中,实现将始终为缩进结构但不同的匿名类型返回相同的值,这是明智的吗?
好吧,在你因为互联网上发布了数百个类似的声音问题而疯狂之前,我可以向你保证,我刚刚花了几个小时阅读所有这些问题并且没有找到我的问题的答案.
基本上,我的一个大型应用程序遇到了这样的情况:属性Binding
上的某些s ListBox.SelectedItem
将停止工作,或者在对当前所选项目进行编辑后程序将崩溃.我最初询问'已经添加了相同键的项目'从代码问题中选择ListBoxItem的例外,但没有得到答案.
直到本周,我才有时间解决这个问题.现在简而言之,我找出了问题的原因.这是因为我的数据类型类已经覆盖了Equals
方法,因此也覆盖了方法GetHashCode
.
现在对于那些不知道这个问题的人,我发现你只能GetHashCode
使用不可变字段/属性来实现该方法.使用Harvey Kwok对Overriding GetHashCode()帖子的回答摘录来解释这个:
问题是Dictionary和HashSet集合正在使用GetHashCode将每个项目放在存储桶中.如果基于某些可变字段计算哈希码,并且在将对象放入HashSet或Dictionary后实际更改了字段,则无法再从HashSet或Dictionary中找到该对象.
所以实际问题是因为我在方法中使用了可变属性GetHashCode
.当用户在UI中更改这些属性值时,对象的关联哈希码值会发生更改,然后在其集合中无法再找到项目.
所以,我的问题是处理我需要GetHashCode
在没有不可变字段的类中实现方法的情况的最佳方法是什么?对不起,让我更加具体,因为该问题已被问过.
Overriding GetHashCode()帖子中的答案表明,在这些情况下,最好只返回一个常量值...一些建议返回值1
,而其他建议返回一个素数.就个人而言,我看不出这些建议之间有任何区别,因为我认为只有一个桶用于其中任何一个.
此外,Eric Lippert博客中关于GetHashCode的指南和规则有一个标题为指南的部分:哈希码的分布必须是"随机的",这突出了使用导致使用不足的桶的算法的缺陷.他警告说,算法会减少使用的桶数,并在桶变得非常大时导致性能问题.当然,返回常数属于这一类.
我想到了Guid
为我的所有数据类型类(仅在C#中,而不是数据库中)添加一个额外的字段,特别是在GetHashCode
方法中使用.所以我想在这个长篇介绍的最后,我的实际问题是哪个实现更好?总结一下:
在没有不可变字段的类中重写Object.GetHashCode()时,最好从GetHashCode
方法返回一个常量,还是readonly
为每个类创建一个附加字段,仅用于GetHashCode
方法?如果我应该添加一个新字段,它应该是什么类型,我不应该将它包含在Equals
方法中?
虽然我很高兴收到任何人的答案,但我真的希望得到高级开发人员的答案,他们对这个主题有充分的了解.
在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)
或者我应该做些什么?
gethashcode ×10
c# ×7
.net ×6
equals ×3
class ×2
comparison ×2
hash ×1
hashcode ×1
mutable ×1
nhibernate ×1
overriding ×1
performance ×1