C# 字典相等要求
Dictionary
的键是否需要进行相等比较?
例如,
Class mytype
{
public bool equals(mytype other)
{
return ...;
}
}
在我的例子中,除非它们是同一个实例,否则它们不会相等。
如果我需要实现相等,我是否应该有一个大数值,该数值随着 mytype
创建的每个新实例而递增?
Do the keys of a Dictionary
need to be comparable with equality?
For example
Class mytype
{
public bool equals(mytype other)
{
return ...;
}
}
In my case they won't be equal unless they are the same instance.
If I need to implement equality should I have a large numeric value that increments with every new instance of mytype
created?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您的类仅在相同实例时才
相等
,那么您无需执行任何操作即可在字典
中使用它们。当且仅当引用同一个对象时,类(引用类型)才被认为是相等的。来自 GetHashCode 的文档
对于派生类对于 Object,GetHashCode 方法可以委托给 Object.GetHashCode 实现,当且仅当该派生类将值相等性定义为引用相等性并且类型不是值类型时。
在您的情况下这似乎是正确的。根据经验,如果您覆盖 Equal,您还需要覆盖 GetHashCode,但这在您的情况下不是必需的,因为默认值就是您正在寻找的。
If your classes are only
equal
if they are same instance, then you don't need to do anything to use them in aDictionary
. Classes (reference types) are considered equal if and only if the refer to the same object.From the documentation of GetHashCode
For derived classes of Object, the GetHashCode method can delegate to the Object.GetHashCode implementation, if and only if that derived class defines value equality to be reference equality and the type is not a value type.
Which seems to be true in your case. As a rule of thumb, if you override Equal you need to override GetHashCode as well but this is not necessary in your case as the default is what you are looking for.
默认情况下,相等性基于实例。两个单独的实例永远不会相等。您只能通过提供自己的 Equals 方法来更改它。
By default, equality is based on the instance. Two separate instances are never equal. You can only change that by providing your own Equals method.
仅当它们被用作键并且您不想将等效性建立在对象本身的实例上时。如果您只希望对完全相同的实例的引用是等效的,那么您不需要执行任何操作,但是如果您使用类型作为键,并且希望“等效”实例被视为相等,则您的类必须实现 <代码>Equals() 和
GetHashCode()
。如果您的自定义类型被存储为值,而不是用作键,那么当然这是没有必要的。例如,在这种情况下,MyType 不需要重写
Equals()
或GetHashCode()
,因为它仅用作值,而不用作存储键。但是在这种情况下:
您的自定义类型是关键,因此需要重写
Equals()
和GetHashCode()
。GetHashCode()
用于确定散列到哪个位置,Equals()
用于解决散列码上的冲突(除其他外)。在处理许多
LINQ
查询时,您还需要重写相同的两个方法。或者,您可以在类之外提供一个独立的IEqualityComparer
来确定两个实例是否等效。Only if they are being used as a key and you don't want to base equivalence on the instance of the object itself. If you only want references to the exact same instance to be equivalent, you are fine and need do nothing, but if you are using your type as a key, and you want "equivalent" instances to be considered equal, your class must implement
Equals()
andGetHashCode()
.If your custom type is being stored as a value, and not used as a key, this is not necessary, of course. For example, in this case MyType does not need to override
Equals()
orGetHashCode()
because it is only used as a value, and not as the storage key.However in this case:
Your custom type is the key, and thus it would need to override
Equals()
andGetHashCode()
. TheGetHashCode()
is used to determine which location it hashes to, and theEquals()
is used to resolve collisions on the hash code (among other things).You'd need to override the same two methods when dealing with many
LINQ
queries as well. Alternatively, you can provide a standaloneIEqualityComparer
apart from your class to determine if two instances are equivalent.请参阅 EqualityComparer.Default 属性。如果您不提供相等比较器,这就是字典如何获取相等比较器的方式。
这将返回一个基于类型 & 的相等比较器。 。
例如,如果 T 扩展了 IEquatable,EqualityComparer.Default 将返回使用 IEquatable 接口的相等比较器实例 否则,它将返回一个使用 Object.Equals 方法的相等比较器实例。
默认情况下,对于引用类型,Object.Equals 方法使用引用相等 (Object.ReferenceEquals),除非您使用自定义比较覆盖它。
默认情况下,值类型的 Object.Equals 方法使用反射来比较结构体的字段是否相等*。反射很慢,这就是为什么总是建议重写值类型中的 Equals。
* 除非它是 blittable 值类型,在这种情况下会比较原始位。
See the EqualityComparer.Default<T> property. This is how the dictionary obtains an equality comparer if you don't supply it with one.
This returns an equality comparer based on the type & capabilities of T.
For example, if T extends IEquatable, EqualityComparer.Default will return an equality comparer instance that uses the IEquatable interface. Otherwise it will return an equality comparer instance that uses the Object.Equals method.
The Object.Equals method, by default for reference types, uses reference equality (Object.ReferenceEquals) unless you override it with a custom comparison.
The Object.Equals method, by default for value types, uses reflection to compare the fields of the struct for equality*. Reflection being slow, this is why it's always recommended to override Equals in value types.
* unless it's a blittable value type in which case the raw bits are compared.
否,
Dictionary没有类型限制
No, there are no type constraints on
Dictionary<TKey, TValue>