对象作为字典中的键
我有这样的课程:
class A {
string name;
string code;
}
示例:
A1: name="blabla", code="kuku"
A2: name="blabla", code=null
A3: name=null, code="kuku"
Dictionary<A, string> d=new Dictionary<A, string>();
d[A1]="aaa";
d[A2]="bbb"
results: d[A1]="bbb";
d[A1]="aaa";
d[A3]="bbb"
results: d[A1]="bbb";
d[A2]="aaa";
d[A3]="bbb"
results: d[A2]="aaa"; d[A3]="bbb";
有没有办法将 A 类实现为字典的键?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你不能。
Equals
/GetHashCode
实现必须形成[等价关系] - 它们必须满足以下属性:你的定义是不传递的;
(a, b)
==(b, c)
和(b, c)
==(c, d)< /code> 但
(a, b)
!=(c, d)
。You can't.
Equals
/GetHashCode
implementations must form an [equivalence relation] - they must satisfy the following properties:Your definition is not transitive;
(a, b)
==(b, c)
and(b, c)
==(c, d)
but(a, b)
!=(c, d)
.更好的选择是实现您自己的
IEqualityComparer
并将其传递给字典的构造函数,而不是实现GetHashCode
。话虽如此,您的等效规则没有意义。编程中的等价必须遵循标准代数等价规则。在您的情况下,您有三个被视为“相等”的对象,这似乎基于两个属性之一是否相等。然而,这种方法没有提供必需的传递相等性。 #1=#2 因为名字。 #1=#3 因为代码。然而,相等和等价要求如果a=b且b=c,则a=c。在您的情况下,比较 #2 和 #3 显示不等价或相等,因为它们没有匹配的属性,即使它们都等于 #1。
简单来说,您的相等/等价规则不能与任何基于密钥的存储库一起使用,例如
Dictionary
。如果您确信这是正确的方式去,那么这将做你正在寻找的事情,但是这不会一致地表现。使用这种伪等价,没有任何东西可以表现一致。。
然而,打破这个很容易:
这里,
dict[A1]
是“baz”
,正如预期的那样。然而,dict[A2]
也是"baz"
,即使A2
不等于A3
根据这些规则。这是因为使用的原始对象是A1
,它等于两者。Rather than implementing
GetHashCode
, a better option would be to implement your ownIEqualityComparer<A>
and pass that to the constructor for your dictionary. That being said, your rules for equivalence don't make sense. Equivalence in programming must follow standard algebraic equivalence rules.In your case, you have three objects that are considered "equal", which seems to be based on whether or not one of two properties is equal. However, this approach doesn't provide for transitive equality, which is required. #1=#2 because of the name. #1=#3 because of the code. However, equality and equivalence requires that if a=b and b=c, then a=c. In your case, comparing #2 to #3 shows no equivalence or equality since they have no matching properties, even though they're both equal to #1.
The short version is that your rules for equality/equivalence cannot be used with any key-based repository, such as
Dictionary
.If you're convinced that this is the right way to go, then this will do what you're looking for, but this will not behave consistently. Nothing can behave consistently using this pseudo-equivalence.
However, it's very easy to break this:
Here,
dict[A1]
is"baz"
, as expected. However,dict[A2]
is also"baz"
, even thoughA2
is not equal toA3
according to these rules. This is because the original object used wasA1
, which is equal to both.要回答您编辑的问题:
创建两个不同的字符串字典(一个用于名称,一个用于代码)并搜索您有值的一个。
To answer your edited question:
Make two different string dictionaries (one for Name and one for Code) and search whichever one you have a value for.