C# 字典相等要求

发布于 2024-12-25 16:21:50 字数 273 浏览 1 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

明媚殇 2025-01-01 16:21:50

如果您的类仅在相同实例时才相等,那么您无需执行任何操作即可在字典中使用它们。当且仅当引用同一个对象时,类(引用类型)才被认为是相等的。

来自 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 a Dictionary. 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.

余生共白头 2025-01-01 16:21:50

默认情况下,相等性基于实例。两个单独的实例永远不会相等。您只能通过提供自己的 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.

画尸师 2025-01-01 16:21:50

仅当它们被用作键并且您不想将等效性建立在对象本身的实例上时。如果您只希望对完全相同的实例的引用是等效的,那么您不需要执行任何操作,但是如果您使用类型作为键,并且希望“等效”实例被视为相等,则您的类必须实现 <代码>Equals() 和GetHashCode()

如果您的自定义类型被存储为值,而不是用作键,那么当然这是没有必要的。例如,在这种情况下,MyType 不需要重写 Equals()GetHashCode(),因为它仅用作值,而不用作存储键。

Dictionary<string, MyType> x;

但是在这种情况下:

Dictionary<MyType, string> x;

您的自定义类型是关键,因此需要重写 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() and GetHashCode().

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() or GetHashCode() because it is only used as a value, and not as the storage key.

Dictionary<string, MyType> x;

However in this case:

Dictionary<MyType, string> x;

Your custom type is the key, and thus it would need to override Equals() and GetHashCode(). The GetHashCode() is used to determine which location it hashes to, and the Equals() 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 standalone IEqualityComparer apart from your class to determine if two instances are equivalent.

荒芜了季节 2025-01-01 16:21:50

请参阅 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.

北恋 2025-01-01 16:21:50

否,Dictionary没有类型限制

No, there are no type constraints on Dictionary<TKey, TValue>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文