自定义类作为 C# 中字典的键不起作用

问题描述 投票:0回答:2

我最近开始学习 C#,但陷入了这个特殊情况。是的,我已经检查了前面的问题,但无法弄清楚我的代码中的问题是什么。 自定义类用作字典中的键,但未找到键 这是我能找到的最接近的答案,但这里给出的答案似乎对我不起作用。

我有一个字典注册表。 Customers 是一个具有 2 个字符串的类:s1 和 s2。客户可以匹配 s1 或 s2(两者都不是必需的)。

类客户:

public class Customers
    {
        public string _s1;
        public string _s2;

        public Customers(string s1, string s2)
        {
            _s1 = s1;
            _s2 = s2;
        }

        public class EqualityComparer : IEqualityComparer<Customers>
        {
            public bool Equals(Customers x, Customers y)
            {
                Console.WriteLine("Inside Equals");
                return ((x._s1.Equals(y._s1)) || (x._s2.Equals(y._s2)));
            }
            public int GetHashCode(Customers x)
            {
                return x._s1.GetHashCode() ^ x._s2.GetHashCode();
            }
        }
    }

程序.cs:

Dictionary<Customers, string> registry = new Dictionary<Customers, string>(new Customers.EqualityComparer());

Customers key = new Customers("1", "2");
Customers key2 = new Customers("12", "21");
registry.Add(key, "12");
registry.Add(key2, "22");
Customers lookUp1 = new Customers("1", "2");
Customers lookUp2 = new Customers("1", "32");
if (registry.ContainsKey(lookUp2))
{
    Console.WriteLine("Found");
}
else
{
    Console.WriteLine("Not Found");
}

问题是,当 s1 和 s2 都匹配时,我会得到“找到”,但是当只有其中一个时,尽管相应地更改了 Equals() 并给出了新 EqualityComparer 的引用,我还是得到了“未找到”也是构造函数。

另外,对于lookup1,我确实得到“内部等于”,但对于lookup2却没有,我不知道为什么。

c# dictionary hash equality
2个回答
9
投票

您对平等设计有问题。每个平等对应必须遵循这些规则:

  1. A.Equals(A) == true
    所有人
    A
  2. 如果
    A.Equals(B) == true
    那么
    B.Equals(A) == true
    对于所有
    A, B
  3. 如果
    A.Equals(B) && B.Equals(C) == true
    那么
    A.Equals(C) == true
    对于所有
    A, B, C

正如我们所见,规则#3(传递规则)已被破坏

   Customer A = new Customer("x", "y");
   Customer B = new Customer("x", "z");
   Customer C = new Customer("p", "z");

由于平等的实现不正确

Dictionary<K, V>
无法正常工作


2
投票
发生这种情况是因为

Dictionary

 基本上是一个 
哈希表:

使用键检索值非常快,接近 O(1),因为

Dictionary<TKey,TValue>

 类是作为 
哈希表实现的。

匹配的第一条规则是哈希码应该相等,并且

"1".GetHashCode() ^ "2".GetHashCode()

(对于
key
)肯定与
"1".GetHashCode() ^ "32".GetHashCode()
(对于
lookUp2
)不同。

© www.soinside.com 2019 - 2024. All rights reserved.