C# 如何在通用哈希表实现中哈希通用键?

C# 如何在通用哈希表实现中哈希通用键?,c#,.net,function,generics,hash,C#,.net,Function,Generics,Hash,我正在使用泛型实现哈希表,就像在c#中实现的字典一样,但我被困在哈希函数部分。我成功地在generic one中重写了哈希表的非泛型实现,但您会在代码中注意到,我不知道如何对Tkey进行哈希 class Node<T, U> { public T key; public U value; public Node<T, U> next; public Node(T key, U value, Node<T, U> next)

我正在使用泛型实现哈希表,就像在c#中实现的字典一样,但我被困在哈希函数部分。我成功地在generic one中重写了哈希表的非泛型实现,但您会在代码中注意到,我不知道如何对Tkey进行哈希

class Node<T, U>
{
    public T key;
    public U value;
    public Node<T, U> next;
    public Node(T key, U value, Node<T, U> next)
    {
        this.key = key;
        this.value = value;
        this.next = next;
    }
 }

public  class HashTable<T,U>
{
    int length;
    Node<T,U>[] buckets;
    public HashTable(int length)
    {
        this.length = length;
        buckets = new Node<T,U>[length];
    }

    public void Display()
    {
        for (int bucket = 0; bucket<buckets.Length; bucket++)
        {
            Node<T,U> current = buckets[bucket];
            Console.Write(bucket + ":");
            while (current != null)
            {
                Console.Write("["+current.key+","+current.value+"]");
                current=current.next;
            }
            Console.WriteLine();
        }
    }
     //  private int Hash(T Tkey) ...
    //// non-generic version of hash function

    private int Hash(string str)
    {
        int h=0;
        foreach(var s in str)
            h=127*h+s;
        return h%length;

    }
     ////
    public void Insert(T key, U value)
    {
        int bucket = Hash(key);
        buckets[bucket] = new Node<T,U>(key, value, buckets[bucket]);
    }
    public U Search(T key)
    {
        Node<T,U> current = buckets[Hash(key)];
        while (current != null)
        {
            if (current.key.Equals(key))
                return current.value;
            current= current.next;
        }
        throw new Exception(key+ "Not found");
    }
类节点
{
公钥;
公共价值观;
公共节点下一步;
公共节点(T键、U值、节点下一步)
{
this.key=key;
这个值=值;
this.next=next;
}
}
公共类哈希表
{
整数长度;
节点[]个桶;
公共哈希表(整数长度)
{
这个长度=长度;
bucket=新节点[长度];
}
公共空间显示()
{
对于(int bucket=0;bucket),C#中的基本对象类附带了用于这些情况的方法

有些类有一个很好的实现,其他类只是从
System.Object
继承方法,而不重写它

从MSDN文档中:

GetHashCode
方法的默认实现不保证不同对象的唯一返回值。此外,.NET Framework不保证
GetHashCode
方法的默认实现,并且它返回的值在不同版本的.NET Framework.conseq之间是相同的通常,此方法的默认实现不能用作哈希目的的唯一对象标识符


GetHashCode
方法可以由派生类型重写。值类型必须重写此方法,以提供适合该类型的哈希函数,并在哈希表中提供有用的分布。为了唯一性,哈希代码必须基于实例字段或属性的值,而不是静态字段或属性的值属性。

这是吗?如果是,请适当标记。为什么要编写自己的实现?我想我应该编写自己的哈希函数。首先,GetHashCode不能保证在版本之间产生相同的行为。GetHashCode也可以返回负值,因此我得到索引越界错误。但是,如果我编写:return Math。Abs(Tkey.GetHashCode());在我的散列函数中,我有一些输出,但我认为这是一个愚蠢的解决方案。散列的想法应该是减少冲突的可能性,但我不确定我从中得到了什么。你真的应该使用GetHashCode;由依赖对象来确定对象是否返回相同的散列。只是因为它不工作k与您的方案无关;根据需要调整值以满足您的需求,但要始终这样做。@impeRAtoR,为什么您需要在不同版本之间执行相同的行为?以及使用
Math.Abs()
这里一点也不蠢。
字典
也做了类似的事情。@impeRAtoR:如果对你来说,
GetHashCode
跨平台的一致性很重要,那你就是做错了。如果你在意
GetHashCode
返回负值,那你就是做错了。
GetHashCode
用于生成可用于平衡哈希表。它们不用于任何其他用途,因此请勿将其作为一种用途使用。从技术上讲,您是对的,来自
对象的实现不保证唯一值。但这只是因为
GetHashCode
的大多数实现也不保证唯一值。您如何保证这两个不同的当
string
s比
int
s多得多时,t字符串有不同的哈希码?