使用派生 class 的 C# 字典查找
C# dictionary lookup using derived class
我认为这可能是一个常见问题,但我没有找到任何关于它的 post。
我在下面写了一些伪代码。如果你想编译代码,请忽略这个 post.
所以说两个 classes:一个碱基 class 和一个 child class。注意:classes 都覆盖了 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);
但是,如果我使用派生的 class 搜索 with/o 类型转换
,查找函数将引发 KeyNotFoundException
dict[b];
Dictionary 将计算 B 而不是 A 的 hashcode 并据此引发异常。
一个简单而笨拙的解决方案是基于 B 的 属性.
创建一个新的 A 实例
dict[new A{name = b.name}];
请问有没有更好的解决办法?
您将列表中的对象存储与字典的键混淆了。如果您使用对象作为键,则需要提供对同一对象的引用 - 而不仅仅是具有相同属性的对象。
如果你这样做:
dict.Add(new A{name = "bob"}, someData);
然后这样做
var result = dict[new A{name = "bob"}];
你会得到 'key not found' 因为两个新的 A
是不同的对象。
尝试创建一个 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());
我认为这可能是一个常见问题,但我没有找到任何关于它的 post。
我在下面写了一些伪代码。如果你想编译代码,请忽略这个 post.
所以说两个 classes:一个碱基 class 和一个 child class。注意:classes 都覆盖了 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);
但是,如果我使用派生的 class 搜索 with/o 类型转换
,查找函数将引发 KeyNotFoundExceptiondict[b];
Dictionary 将计算 B 而不是 A 的 hashcode 并据此引发异常。
一个简单而笨拙的解决方案是基于 B 的 属性.
创建一个新的 A 实例dict[new A{name = b.name}];
请问有没有更好的解决办法?
您将列表中的对象存储与字典的键混淆了。如果您使用对象作为键,则需要提供对同一对象的引用 - 而不仅仅是具有相同属性的对象。
如果你这样做:
dict.Add(new A{name = "bob"}, someData);
然后这样做
var result = dict[new A{name = "bob"}];
你会得到 'key not found' 因为两个新的 A
是不同的对象。
尝试创建一个 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());