为什么即使值相同,哈希表中的值比较也会返回false?

Tom*_*Tom 3 c# hashtable

在下面的代码中,我试图检查两个字符串是否是字谜.为此,我计算哈希表中两个字符串中的字符,方法是将唯一字符作为键存储,并将其作为值存储在字符串中.最后,当我去检查,如果每个角色都具有相同的数,我得到一个错误的输出中看到标示为代码"问题"就行了.但是当我将该行中的值转换为字符串时,代码工作正常.我错过了什么?

    static bool AreAnagrams(string input1, string input2)
    {
        Hashtable uniqueChars1 = new Hashtable();
        Hashtable uniqueChars2 = new Hashtable();

        // Go through first string and create a hash table of characters 
        AddToHashTable(input1, ref uniqueChars1);
        // Go through second string and create a second hash table of characters
        AddToHashTable(input2, ref uniqueChars2);

        // For each unique character, if the count from both hash tables are the same, they are anagrams
        if (uniqueChars1.Keys.Count != uniqueChars2.Keys.Count)
        {
            return false;
        }
        else
        {
            foreach (object key in uniqueChars1.Keys)
            {
                if (uniqueChars1[key] != uniqueChars2[key]) // ***PROBLEM HERE***
                {
                    return false;
                }
            }
        }
        return true;
    }

    static void AddToHashTable(string input, ref Hashtable uniqueChars)
    {
        foreach (char c in input)
        {

            if (!uniqueChars.ContainsKey(c))
            {
                uniqueChars.Add(c, 1);
            }
            else
            {
                int charCount = Convert.ToInt32(uniqueChars[c]);
                charCount++;
                uniqueChars[c] = charCount;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

Tho*_*que 5

这个Hashtable班不是通用的; 它只包含Objects,而不是特定类型.

当你这样做:

if (uniqueChars1[key] != uniqueChars2[key])
Run Code Online (Sandbox Code Playgroud)

编译时类型uniqueChars[key]Object,不是Int32.所以你正在使用Object不等式运算符的实现,它只是比较引用.由于Int32是一个值类型,并且索引器返回一个对象,因此该值被加框 ; 并且由于您正在装箱两个值,因此您将获得两个不同的对象实例,因此引用相等性始终返回false.

你有几个选择:

除非您仍在使用.NET 1.x,否则我强烈建议您尽可能使用通用集合.它们更安全,更直观,并且对于价值类型具有更好的性能.


旁注(与您的问题无关):您不需要Hashtable通过引用传递AddToHashTable; 如果没有ref修饰符,代码将以完全相同的方式工作,因为它Hashtable是一个引用类型,所以它始终是一个传递的引用.在ref如果你分配给别的修饰只会是有用的uniqueChars参数,或者如果你是传递一个值类型和变异的状态(这通常认为是一件坏事).我建议你阅读Jon Skeet关于值类型,引用类型和参数传递的精彩文章.