自定义键类 不在字典中[重复]

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

这个问题在这里已有答案:

我试图找出如何使用自定义类作为字典中的键。我的课

public class Enabler
{
    public string Name { get; set; }
    public bool Enabled { get; set; }

    public override int GetHashCode()
    {
        return Name.GetHashCode() ^ Enabled.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as Enabler);
    }

    public bool Equals(Enabler obj)
    {
        return obj != null && obj.Name == this.Name;
    }
}

当我尝试使用它时:

Dictionary<Enabler, List<AppSettingsElement>> appSettings = new Dictionary<Enabler, List<AppSettingsElement>>();
appSettings.Add(new Enabler {Name = "none", Enabled = true }, new List<AppSettingsElement>());
Enabler myKey = new Enabler { Name = "none" };
appSettings[myKey].Add(new AppSettingsElement { Comment = text, Name = name, Value = "value" });
//last line throws "myKey not found in dictionary" error. 

我究竟做错了什么?

c# dictionary
1个回答
4
投票

您的EqualsGetHashCode方法需要兼容。现在,你的GetHashCode方法考虑Enabled,但Equals没有,这可能导致事情不可能。从Enabled删除GetHashCode支票:

    public override int GetHashCode()
    {
        return Name.GetHashCode();
    }

或将其添加到Equals

    public bool Equals(Enabler obj)
    {
        return obj != null && obj.Name == this.Name
            && obj.Enabled == this.Enabled;
    }

注意到第二种选择,myKey需要让Enabled = true成为一个匹配。

注意:可变键是一个糟糕的主意。你应该考虑:

public Enabler(string name, bool enabled)
{
    Name = name;
    Enabled = enabled;
}
public string Name { get; }
public bool Enabled { get; }

使其不可变。

注意:如果你使它成为不可变的,那么它也可能是一个struct,所以:

public struct Enabler
{ ... }

并修复null检查:

public override bool Equals(object obj)
    => Equals(obj is Enabler e && Equals(e));

public bool Equals(Enabler obj)
    => obj.Name == this.Name && obj.Enabled == this.Enabled;

无论哪种方式,你也应该使Enabler实施IEquatable<Enabler>,即

public class Enabler : IEquatable<Enabler>

要么

public struct Enabler : IEquatable<Enabler>
© www.soinside.com 2019 - 2024. All rights reserved.