使用自定义类作为键时,"给定键不存在于字典中"错误

wce*_*ceo 5 c#

我有这样的代码:

if (CounterForEachRelatedTagDict.Select(x => x.Key).Contains(tag.Key))
   CounterForEachRelatedTagDict[tag.Key] += tag.Value;
Run Code Online (Sandbox Code Playgroud)

是否有可能IF语句返回true,同时CounterForEachRelatedTagDict[tag.Key]返回"给定的键不存在于字典中"错误?tag是一个KeyValuePair<MyClass,int>.

CounterForEachRelatedTagDict 像这样发起:

Dictionary<MyClass, int> CounterForEachRelatedTagDict = new Dictionary<MyType, int>();
Run Code Online (Sandbox Code Playgroud)

MyClass 是这样的

public class MyClass
{
    public string name {get;set;}
    public Guid Id { get; set; }
    ...
}
Run Code Online (Sandbox Code Playgroud)

这似乎对我来说几乎是不合理的......

Ser*_*kov 1

要将您的类型用作字典键,您应该重写两个方法:GetHashCodeEquals

默认情况下(如果您不重写GetHashCode)您类型的每个对象(即使具有相同的字段值)都将返回唯一值。这意味着您将只能找到与放入字典中的完全相同的“参考”。考虑以下两种类型:MyType1不覆盖GetHashCodeEquals,以及 MyType2 覆盖:

class MyType1
{
  public MyType1(int id, string name) {Id = id; Name = name;}
  public int Id {get; private set;}
  public string Name {get; private set;}
}


internal class MyType2
{
    public MyType2(int id, string name)
    {
        Id = id;
        Name = name;
    }

    public int Id { get; private set; }
    public string Name { get; private set; }

    bool Equals(MyType2 other)
    {
        return Id == other.Id && string.Equals(Name, other.Name);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((MyType2) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return (Id*397) ^ Name.GetHashCode();
        }
    }
}

var d1 = new Dictionary<MyType1, int>();
d1[new MyType1(1, "1")] = 1;
d1[new MyType1(1, "1")]++; // will throw withKeyNotFoundException

var d2 = new Dictionary<MyType2, int>();
d1[new MyType2(1, "1")] = 1;
d1[new MyType2(1, "1")]++; // Ok, we'll find appropriate record in dictionary
Run Code Online (Sandbox Code Playgroud)