C# 当两个字符串可以互换时,如何为具有两个字符串的结构实现 GetHashCode
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/70303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you implement GetHashCode for structure with two string, when both strings are interchangeable
提问by Graviton
I have a structure in C#:
我在 C# 中有一个结构:
public struct UserInfo
{
public string str1
{
get;
set;
}
public string str2
{
get;
set;
}
}
The only rule is that UserInfo(str1="AA", str2="BB").Equals(UserInfo(str1="BB", str2="AA"))
唯一的规则是 UserInfo(str1="AA", str2="BB").Equals(UserInfo(str1="BB", str2="AA"))
How to override the GetHashCode function for this structure?
如何覆盖此结构的 GetHashCode 函数?
采纳答案by aku
MSDN:
微软:
A hash function must have the following properties:
散列函数必须具有以下属性:
- If two objects compare as equal, the
GetHashCode
method for each object must return the same value. However, if two objects do not compare as equal, theGetHashCode
methods for the two object do not have to return different values.- The
GetHashCode
method for an object must consistently return the same hash code as long as there is no modification to the object state that determines the return value of the object'sEquals
method. Note that this is true only for the current execution of an application, and that a different hash code can be returned if the application is run again.- For the best performance, a hash function must generate a random distribution for all input.
- 如果两个对象比较相等,则
GetHashCode
每个对象的方法必须返回相同的值。但是,如果两个对象不相等,则两个对象的GetHashCode
方法不必返回不同的值。GetHashCode
只要确定对象Equals
方法的返回值的对象状态没有修改,对象的方法就必须始终如一地返回相同的哈希码。请注意,这仅适用于应用程序的当前执行,如果再次运行该应用程序,可能会返回不同的哈希码。- 为了获得最佳性能,散列函数必须为所有输入生成随机分布。
Taking it into account correct way is:
考虑到正确的方法是:
return str1.GetHashCode() ^ str2.GetHashCode()
^
can be substituted with other commutative operation
^
可以用其他交换操作代替
回答by VolkerK
Many possibilities. E.g.
许多可能性。例如
return str1.GetHashCode() ^ str1.GetHashCode()
return str1.GetHashCode() ^ str1.GetHashCode()
回答by Mike Stone
Perhaps something like str1.GetHashCode() + str2.GetHashCode()? or (str1.GetHashCode() + str2.GetHashCode()) / 2? This way it would be the same regardless of whether str1 and str2 are swapped....
也许像 str1.GetHashCode() + str2.GetHashCode() 这样的东西?或 (str1.GetHashCode() + str2.GetHashCode()) / 2?这样,无论 str1 和 str2 是否交换,它都是相同的....
回答by Artem Tikhomirov
Try out this one:
试试这个:
(((long)str1.GetHashCode()) + ((long)str2.GetHashCode())).GetHashCode()
回答by Steve Morgan
Sort them, then concatenate them:
对它们进行排序,然后将它们连接起来:
return ((str1.CompareTo(str2) < 1) ? str1 + str2 : str2 + str1) .GetHashCode();
回答by Omer van Kloeten
GetHashCode's result is supposed to be:
GetHashCode 的结果应该是:
- As fast as possible.
- As unique as possible.
- 尽可能快地。
- 尽可能独特。
Bearing those in mind, I would go with something like this:
考虑到这些,我会采用这样的方法:
if (str1 == null)
if (str2 == null)
return 0;
else
return str2.GetHashCode();
else
if (str2 == null)
return str1.GetHashCode();
else
return ((ulong)str1.GetHashCode() | ((ulong)str2.GetHashCode() << 32)).GetHashCode();
Edit:Forgot the nulls. Code fixed.
编辑:忘记了空值。代码固定。
回答by Grokys
Ah yes, as Gary Shutler pointed out:
是的,正如加里·舒特勒指出的那样:
return str1.GetHashCode() + str2.GetHashCode();
Can overflow. You could try casting to long as Artem suggested, or you could surround the statement in the unchecked keyword:
可以溢出。您可以按照 Artem 的建议尝试强制转换为 long,或者您可以将语句括在 unchecked 关键字中:
return unchecked(str1.GetHashCode() + str2.GetHashCode());
回答by Roger Willcocks
Too complicated, and forgets nulls, etc. This is used for things like bucketing, so you can get away with something like
太复杂了,忘记了空值等。这用于诸如分桶之类的事情,因此您可以摆脱类似
if (null != str1) {
return str1.GetHashCode();
}
if (null != str2) {
return str2.GetHashCode();
}
//Not sure what you would put here, some constant value will do
return 0;
This is biased by assuming that str1 is not likely to be common in an unusually large proportion of instances.
这是由于假设 str1 不太可能在异常大比例的实例中普遍存在而存在偏差。
回答by user11556
public override int GetHashCode()
{
unchecked
{
return(str1 != null ? str1.GetHashCode() : 0) ^ (str2 != null ? str2.GetHashCode() : 0);
}
}
回答by user11556
public override int GetHashCode()
{
unchecked
{
return (str1 ?? String.Empty).GetHashCode() +
(str2 ?? String.Empty).GetHashCode();
}
}
Using the '+' operator might be better than using '^', because although you explicitly want ('AA', 'BB') and ('BB', 'AA') to explicitly be the same, you may not want ('AA', 'AA') and ('BB', 'BB') to be the same (or all equal pairs for that matter).
使用“+”运算符可能比使用“^”更好,因为尽管您明确希望 ('AA', 'BB') 和 ('BB', 'AA') 明确相同,但您可能不希望 ( 'AA', 'AA') 和 ('BB', 'BB') 相同(或所有相等的对)。
The 'as fast as possible' rule is not entirely adhered to in this solution because in the case of nulls this performs a 'GetHashCode()' on the empty string rather than immediately return a known constant, but even without explicitly measuring I am willing to hazard a guess that the difference wouldn't be big enough to worry about unless you expect a lot of nulls.
在此解决方案中并未完全遵守“尽可能快”规则,因为在空字符串的情况下,这会在空字符串上执行“GetHashCode()”,而不是立即返回已知常量,但即使没有明确测量,我也愿意冒险猜测差异不会大到足以担心,除非您期望有很多空值。