【问题标题】:Why doesn't Contains call CompareTo nor Equals?为什么 Contains 不调用 CompareTo 或 Equals?
【发布时间】:2015-03-17 21:41:56
【问题描述】:

在比较自定义类的实例时,我注意到对Contains 的调用没有按我预期的方式工作。假设默认比较是通过引用(指针或其他名称)进行的,我实现了CompareToEquals。当然,我确保实现IComparable

它仍然不起作用,当我在这些方法上设置断点时,我没有得到任何命中。

我可能会遗漏什么,如果我没有,使用扩展方法的最佳选择是什么?

public override bool Equals(Object input)
{
  return Id == ((MyType) input).Id;
}

public int CompareTo(Object input)
{
  return Id - ((MyType)input).Id;
}

【问题讨论】:

  • 您可能需要覆盖GetHashCode(),也可能需要覆盖==。我们在谈论哪个Contains? Linq中的扩展方法? List 中的那个?
  • 你在哪个班级打电话给Contains
  • 另外,关于覆盖 Equals 的信息。 msdn.microsoft.com/en-us/library/ms173147%28v=vs.80%29.aspx
  • @AndyJ 如果您的 MyType 类实现 IEquatable,您仍然“必须”覆盖 GetHashCode(),因为大多数查找首先针对实例的哈希码,请参阅 blogs.msdn.com/b/jaredpar/archive/2009/01/15/…。试一试 - override .GetHashcode() { return base.GetHashCode(); } 并在其中放置一个断点,看看它是否被击中。
  • GetHashCode 是一种预先检查事物是否相等而不执行整个比较的方法。具有相同哈希码的两件事应该是相等的。从理论上讲,hashcode 应该是比整个对象更快的比较,但大多数人没有正确实现它。

标签: c# equals compareto


【解决方案1】:

更好的实现可能是:

public bool Equals(MyType other)
{
    // if 'other' is a null reference, or if 'other' is more derived or less derived
    if ((object)other == (object)null || other.GetType() != GetType())
        return false;

    // OK, check members (assuming 'Id' has a type that makes '==' a wise choice)
    return Id == other.Id;
}

public override bool Equals(object obj)
{
    // call to other overload
    return Equals(obj as MyType);
}

public override int GetHashCode()
{
    return Id.GetHashCode();
}

在这种情况下,您可以将该类标记为实现IEquatable<MyType>(但即使没有它也可以工作)。

关于GetHashCode总是记得覆盖它。您应该已经看到编译器警告,在不覆盖 GetHashCode 的情况下覆盖 Equals(object) 是有问题的。 从不在覆盖中保留代码return base.GetHashCode()(假设基类是System.Object)。要么尝试一下,要么根据参与Equals 的成员来实现一些东西。如果您认为GetHashCode 不会实际用于您的情况,请说:

public override int GetHashCode()
{
    throw new NotSupportedException("We don't have GetHashCode, sorry");
}

如果您绝对知道您只会使用List<>.Contains,而不是例如Dictionary<,>HashSet<> 而不是 Linq 的 Distinct() 等,它可以与 GetHashCode() 一起使用,只需抛出即可。

IComparable<MyType> 是不需要的,除非你排序 List<MyType>MyType[],或者你使用Linq 的OrderByMyType,或者你使用SortedDictionary<,>SortedSet<>

这些用途不需要重载operator ==

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-08
    • 2011-10-10
    • 1970-01-01
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 2012-06-22
    相关资源
    最近更新 更多