这个问题在这里已有答案:
我试图找出如何使用自定义类作为字典中的键。我的课
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.
我究竟做错了什么?
您的Equals
和GetHashCode
方法需要兼容。现在,你的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>