【问题标题】:C# dictionary lookup using derived class使用派生类的 C# 字典查找
【发布时间】:2019-08-22 08:11:59
【问题描述】:

我认为这可能是一个常见问题,但我没有找到任何关于它的帖子。

我在下面写一些伪代码。如果你想编译代码,请忽略这篇文章。

所以说两个类:一个基类和一个子类。注意:这两个类都有重写 Equals() 和 GetHashCode() 函数以确保具有相同属性的相等性。

public class A // A has a string property of name
public class B:A // B has a string property of title

var a = new A{name = "bob"};
var b = new B{name = "bob", title = "em"};

有些代码有一个基于 A 的字典

var dict = new Dictionary<A>();

做一些添加的东西,例如,

dict.Add(a);

但是,如果我使用带有/o 类型转换的派生类搜索,查找函数将引发 KeyNotFoundException

dict[b];

Dictionary 会计算 B 而不是 A 的 hashcode 并据此引发异常。

一个简单而笨拙的解决方案是根据 B 的属性创建一个新的 A 实例。

dict[new A{name = b.name}];

不知道有没有更好的解决方案?

【问题讨论】:

  • 字典是两种类型的通用对象。不只是一个Dictionary&lt;TKey, TValue&gt;。请将问题中的定义更正为可编译的代码。否则很难提供帮助
  • 请创建一个Minimal, Complete, and Verifiable example。您的代码无法编译,不清楚您的类做了什么。特别是需要您的哈希码实现。
  • “如果你想编译代码,请忽略这篇文章” - 如果这只是伪代码,那么你希望我们如何帮助你处理实际的异常?一切都是伪中的“工作”/“有效”......对不起,但这不是一个写得很好的SO问题......任何人都很难提供帮助
  • 感谢您的建议。但我认为如果伪代码不能帮助理解问题,那么答案肯定也毫无用处。
  • 经过几天的调查和试用,IEqualityComparer 可能是一个很好的解决方案,建议如下。再次感谢大家的快速回复,但也请确保您阅读并理解问题。不仅仅是复制和粘贴代码并尝试运行它。

标签: c# dictionary derived-class


【解决方案1】:

尝试创建一个 EqualityComparer,并在字典的构造函数中传递它的一个实例。

class AEqualityComparer : IEqualityComparer<A>
{
    public bool Equals(A x, A y)
    {
        return x.Equals(y);
    }

    public int GetHashCode(A obj)
    {
        return obj.GetHashCode();
    }
}

var dict = new Dictionary<A, object>(new AEqualityComparer());

【讨论】:

    【解决方案2】:

    您将在列表中存储对象与字典的键混淆了。如果您使用对象作为键,则需要提供对同一对象的引用 - 而不仅仅是具有相同属性的对象。

    如果你这样做:

    dict.Add(new A{name = "bob"}, someData);
    

    然后这样做

    var result = dict[new A{name = "bob"}];
    

    您将收到“未找到密钥”,因为这两个新的 As 是不同的对象。

    【讨论】:

    • 是的,我忘了提到这两个类都有覆盖 Equality() 和 GetHashCode() 函数用于属性比较
    猜你喜欢
    • 1970-01-01
    • 2021-07-29
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    相关资源
    最近更新 更多