【问题标题】:C# dictionary equality requirementC# 字典相等要求
【发布时间】:2012-02-04 06:53:59
【问题描述】:

Dictionary 的键是否需要与相等性进行比较?

例如

Class mytype
{
    public bool equals(mytype other)
    {
        return ...;
    }
}

在我的情况下,除非它们是同一个实例,否则它们不会相等。

如果我需要实现相等,我是否应该有一个随着 mytype 的每个新实例创建而递增的大数值?

【问题讨论】:

    标签: c# collections dictionary set equality


    【解决方案1】:

    如果您的类只是equal(如果它们是相同的实例),那么您无需做任何事情就可以在Dictionary 中使用它们。当且仅当引用相同的对象时,类(引用类型)才被认为是相等的。

    From the documentation of GetHashCode

    对于 Object 的派生类,GetHashCode 方法可以委托给 Object.GetHashCode 实现,当且仅当该派生类将值相等定义为引用相等且类型不是值类型。

    在您的情况下这似乎是正确的。根据经验,如果您覆盖 Equal,您还需要覆盖 GetHashCode,但在您的情况下这不是必需的,因为您正在寻找默认值。

    【讨论】:

      【解决方案2】:

      默认情况下,相等性基于实例。两个单独的实例永远不会相等。您只能通过提供自己的 Equals 方法来更改它。

      【讨论】:

      • 你还想实现GetHashCode()
      【解决方案3】:

      仅当它们被用作键并且您不想将等价基于对象本身的实例时。如果您只希望对完全相同的实例的引用是等价的,那么您很好,不需要做任何事情,但是如果您使用您的类型作为键,并且您希望“等价”实例被认为是相等的,那么您的类必须实现 @ 987654321@和GetHashCode()

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

      Dictionary<string, MyType> x;
      

      但是在这种情况下:

      Dictionary<MyType, string> x;
      

      您的自定义类型是关键,因此它需要覆盖Equals()GetHashCode()GetHashCode() 用于确定它散列到哪个位置,Equals() 用于解决散列码上的冲突(除其他外)。

      在处理许多LINQ 查询时,您还需要覆盖相同的两个方法。或者,您可以在您的类之外提供一个独立的IEqualityComparer,以确定两个实例是否等效。

      【讨论】:

      • 但是如果引用相等是期望的行为,那么类型不应该覆盖这些方法,并且OP似乎表明引用相等期望的行为。
      • @phoog:好问题,他的陈述“在我的情况下,除非它们是同一个实例,否则它们不会相等”对我来说可以以“这就是它正在做的事情”或“这就是我想要它做的”,我更新了我的答案以反映任何一种方式。
      【解决方案4】:

      查看EqualityComparer.Default<T> 属性。如果您不提供相等比较器,这就是字典如何获得相等比较器的方式。

      这会根据 T 的类型和能力返回一个相等比较器。

      例如,如果 T 扩展了 IEquatable,则 EqualityComparer.Default 将返回一个使用 IEquatable 接口的相等比较器实例。否则它将返回一个使用 Object.Equals 方法的相等比较器实例。

      对于引用类型,Object.Equals 方法默认使用引用相等 (Object.ReferenceEquals),除非您使用自定义比较覆盖它。

      对于值类型,Object.Equals 方法默认使用反射来比较结构的字段是否相等*。反射很慢,这就是为什么总是建议在值类型中覆盖 Equals。

      * 除非它是 blittable 值类型,在这种情况下会比较原始位。

      【讨论】:

        【解决方案5】:

        不,Dictionary&lt;TKey, TValue&gt; 没有类型限制

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-01-19
          • 2012-05-27
          • 2011-04-17
          • 1970-01-01
          • 1970-01-01
          • 2013-10-09
          • 2016-06-07
          相关资源
          最近更新 更多