创建';好';.NET ala Boost.Functional/hash的哈希代码 对于C++,我一直使用来创建好的散列值,而不必处理位移位、XOR和素数。是否有任何库可以为C#/.NET生成好的(我不是要求最佳的)散列值?我将使用此实用程序实现GetHashCode(),而不是加密哈希

创建';好';.NET ala Boost.Functional/hash的哈希代码 对于C++,我一直使用来创建好的散列值,而不必处理位移位、XOR和素数。是否有任何库可以为C#/.NET生成好的(我不是要求最佳的)散列值?我将使用此实用程序实现GetHashCode(),而不是加密哈希,c#,.net,hash,C#,.net,Hash,为了阐明为什么我认为这很有用,下面是结合到哈希值的boost::hash\u combine的实现(当然,这是实现GetHashCode()时非常常见的操作): seed^=hash_值(v)+0x9e3779b9+(seed>2); 显然,这类代码不属于GetHashCode()的实现,因此应该在其他地方实现。看看这个,它描述了MD5哈希。 否则,请使用GetHashCode()。除非您有非常具体的要求,否则不需要根据第一原理计算类型的hashcode。而是以一种简单的方式组合用于确定相等性

为了阐明为什么我认为这很有用,下面是结合到哈希值的
boost::hash\u combine
的实现(当然,这是实现GetHashCode()时非常常见的操作):

seed^=hash_值(v)+0x9e3779b9+(seed>2);

显然,这类代码不属于
GetHashCode()
的实现,因此应该在其他地方实现。

看看这个,它描述了MD5哈希。
否则,请使用GetHashCode()。

除非您有非常具体的要求,否则不需要根据第一原理计算类型的hashcode。而是以一种简单的方式组合用于确定相等性的字段/属性的哈希代码,例如:

int hash = field1.GetHashCode();
hash = (hash *37) + field2.GetHashCode();
(组合函数取自§3.3.2)。

的答案包含一些类似于Boost.Functional/Hash的助手类示例。不过,没有一个看起来那么优雅


我不知道有哪一个真正的.NET库提供了类似的功能。

我不会为此使用单独的库。如前所述,对于
GetHashCode
方法,快速和稳定是至关重要的。通常我更喜欢编写内联实现,但实际上使用帮助器类可能是个好主意:

internal static class HashHelper
{
    private static int InitialHash = 17; // Prime number
    private static int Multiplier = 23; // Different prime number

    public static Int32 GetHashCode(params object[] values)
    {
        unchecked // overflow is fine
        {
            int hash = InitialHash;

            if (values != null)
                for (int i = 0; i < values.Length; i++)
                {
                    object currentValue = values[i];
                    hash = hash * Multiplier
                        + (currentValue != null ? currentValue.GetHashCode() : 0);
                }

            return hash;
        }
    }
}

要避免装箱问题,请在Int32上使用泛型扩展方法进行调用

public static class HashHelper
{
    public static int InitialHash = 17; // Prime number
    private static int Multiplier = 23; // Different prime number

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static Int32 GetHashCode<T>( this Int32 source, T next )
    {
        // comparing null of value objects is ok. See
        // http://stackoverflow.com/questions/1972262/c-sharp-okay-with-comparing-value-types-to-null
        if ( next == null )
        {
            return source;
        }
        unchecked
        {
            return source + next.GetHashCode();
        }
    }

}

如何定义好的散列?为了什么?你为什么不喜欢
GetHashCode()
?我想你误解了操作。他想在
GetHashCode
中使用类似Boost.Functional/Hash的东西!相关:@CodeInChaos:我喜欢GetHashCode(),我只是想要一个更好的方法来实现它。大多数开发人员最后只做了
\u member1.GetHashCode()+\u member2.GetHashCode()
等。“显然,这种代码不属于
GetHashCode()
的实现”:我看不出有任何理由不这样做,除非您编写了很多这样的合并,然后转到一个助手函数。OP不是在谈论加密哈希,更像是
GetHashCode
等使用的哈希函数。@Richard&@LukeH-请仔细阅读问题,他不想要最优的解决方案,而是一个好的解决方案。检查更新的问题:这是一个关于
GetHashCode
实现的问题。使用31而不是37。37可能会导致退化哈希,因为字典有时会选择它作为容量。@CodeInChaose:我怀疑当考虑整个系统时,任何值都会有退化情况。请随意选择更好的值——在一般用途的回答中,它们基本上是任意的。
public override int GetHashCode()
{
    return HashHelper.GetHashCode(field1, field2);
}
public static class HashHelper
{
    public static int InitialHash = 17; // Prime number
    private static int Multiplier = 23; // Different prime number

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static Int32 GetHashCode<T>( this Int32 source, T next )
    {
        // comparing null of value objects is ok. See
        // http://stackoverflow.com/questions/1972262/c-sharp-okay-with-comparing-value-types-to-null
        if ( next == null )
        {
            return source;
        }
        unchecked
        {
            return source + next.GetHashCode();
        }
    }

}
HashHelper
    .InitialHash
    .GetHashCode(field0)
    .GetHashCode(field1)
    .GetHashCode(field2);