【问题标题】:Use Override functions(GetHashCode) from Library Collections(HashSet) with an interface type parameter使用带有接口类型参数的库集合(HashSet)中的覆盖函数(GetHashCode)
【发布时间】:2020-11-25 10:34:14
【问题描述】:

我有界面旋转。由 QuarterRotation 类实现:

public interface Rotation {
     bla...
}

还有一个实现:

public class QuarterRotation: Rotation,  IEquatable<QuarterRotation>{
     constructor etc.. bla...
     public override GetHashCode() {
        return [nice number to describe equality]
     }
     public override Equals(QuarterRotation other) {
        return [equal when direction and rotation amount is equal]
     }
}

不,我想把它放在这样的 HashSet 中,但相等性不成立:

var set = new HashSet<Rotation>() {new QuarterRotation(x,0)};
set.Contains(new QuarterRotation(x,0)); // should be true in my mind, but is false

这是由于我的自定义覆盖 GetHashCode 和 Equals 没有被调用,而是调用了 Object 版本。

这确实有效:

var set = new HashSet<QuarterRotation>() {new QuarterRotation(x,0)};
set.Contains(new QuarterRotation(x,0)); // is true

但这不是我的梦想。因为我不想承诺一种轮换。在 C# 中是否有可能我可以将这样的接口用于 HashSet?我觉得我理解的实际问题,但如果我错了,请纠正我。还可以进一步解释为什么从抽象的角度考虑不同的方式来解决此类集合是明智的,至少在 C# 中是这样的。

【问题讨论】:

  • 你的班级为什么要实现IEqualityComparer&lt;T&gt;?它不实现此接口的成员。你的意思是IEquatable&lt;T&gt;
  • 你也应该覆盖Equals(object)
  • 恐怕你的问题不清楚。 HashSet&lt;T&gt; 将使用默认的相等比较器 EqualityComparer&lt;T&gt;.Default。如果您的类型实现了IEquatable&lt;T&gt;,那么这将调用IEquatable&lt;T&gt;.Equals(T) 方法,否则它将调用object.Equals(object)(这只是为了避免在T 是值类型时装箱)。如果您实现自己的平等,您必须覆盖object.Equals(object)。除非T 是值类型,否则实现IEquatable&lt;T&gt; 并没有什么意义,但如果你这样做,object.Equals(object) 通常会调用IEquatable&lt;T&gt;.Equals(T)
  • @canton7 是的,谢谢,应该是平等的
  • @canton7 哦,不错,肯定忘了实现override Equals(object),还以为界面会遮住我……我就放上去,看看你是否让我梦想成真!跨度>

标签: c# interface hashset hashcode


【解决方案1】:

在 QuarterRotation 中使用 override 选项实现 Equals(Object obj) 修复了它,这使得 HashSet 使用该函数。它与 HashSet 类型参数中给出的接口完全分开(我假设它在运行时找到函数的 Equals 方法)。谢谢@canton7 和@Klausgutter

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-13
    • 2013-09-11
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 2015-12-07
    • 2014-01-03
    • 2011-01-08
    相关资源
    最近更新 更多