通常期望Equals(Object)
并且IEquatable<T>.Equals(T)
应该实现等价关系,这样如果观察到 X 等于 Y,并且观察到 Y 等于 Z,并且没有任何项目被修改,则可以假设 X 等于Z; 此外,如果 X 等于 Y 并且 Y 不等于Z,则可以假定 X 也不等于 Z。通配符和模糊比较方法不实现等价关系,因此Equals
一般不应该用这种语义来实现。
许多集合将有点与以Equals
不实现等价关系的方式实现的对象一起工作,前提是任何两个可能相互比较相等的对象总是返回相同的哈希码。这样做通常需要许多比较不相等的东西来返回相同的哈希码,尽管根据支持的通配符类型,可能在某种程度上分离项目。
例如,如果特定字符串支持的唯一通配符表示“一个或多个数字的任意字符串”,则可以通过将所有连续数字序列和/或数字字符串通配符转换为单个“字符串位数”通配符。如果 # 代表任何数字,则字符串 abc123、abc#、abc456 和 abc#93#22#7 将全部散列到与 abc# 相同的值,但 abc#b、abc123b 等可以散列到不同的值价值。根据字符串的分布,这种区别可能会也可能不会产生比返回常量值更好的性能。
请注意,即使GetHashCode
以相等对象产生相等哈希的方式实现,如果相等方法未实现等价关系,某些集合仍可能表现异常。例如,如果集合foo
包含键为“abc1”和“abc2”的项目,则尝试访问foo["abc#"]
可能会任意返回第一项或第二项。尝试删除键“abc#”可能会任意删除一项或两项,或者在删除一项后可能会失败(其预期的后置条件不会满足,因为abc#
即使在删除后也会在集合中)。
与其尝试Equals
比较哈希码相等性,另一种方法是使用一个字典,该字典为每个可能匹配至少一个主集合字符串的通配符字符串保存一个它可能匹配的字符串列表。因此,如果有许多匹配 abc# 的字符串,它们可能都有不同的哈希码;如果用户输入“abc#”作为搜索请求,系统将在通配符字典中查找“abc#”并接收与该模式匹配的所有字符串的列表,然后可以在主字典中单独查找.