【问题标题】:IEqualityComparer<T> does not work with List<T>.Distinct() methodIEqualityComparer<T> 不适用于 List<T>.Distinct() 方法
【发布时间】:2015-07-01 06:13:37
【问题描述】:

我有以下简单的对象:

public class Net : IEqualityComparer<Net>
{
    public string Name { get; private set; }
    public int Id { get; set; }

    private Gate _inGate;
    private Gate _outGate;
    private NetValue _value = NetValue.NotSet;
    private bool _isMiddleNet;

    //constructor and stuff!!!.....

    //Equality comparer
    public bool Equals(Net x, Net y)
    {
        return (x.Id == y.Id && x.Name == y.Name);
    }

    public int GetHashCode(Net obj)
    {
        return obj.Id.GetHashCode() ^ obj.Name.GetHashCode();
    }

    public override int GetHashCode()
    {
        return 13 * Id.GetHashCode() + 7 * Name.GetHashCode();
    }

所以基本上我有兴趣说这个对象的 2 个实例是相等的,当且仅当它们的 IdName 成员相等时...

但是在另一个班级的其他地方我必须List&lt;Net&gt;,我想对这些列表进行区分:

    inputNetsA = inputNetsA.Distinct().ToList();
    inputNetsB = inputNetsB.Distinct().ToList();

但这从来都不起作用!我做错了什么?

【问题讨论】:

  • Side q:为什么 GetHashCode 的 2 个实现在您的示例中如此不同? object.Equals 的实现在哪里?有关信息,请参阅stackoverflow.com/questions/4095395/… 和链接问题...

标签: c# .net linq iequalitycomparer


【解决方案1】:

您需要创建对象IEquatable&lt;T&gt;IEqualityComparer&lt;T&gt; 是一个对象接口,用于比较两个对象。 IEquatable&lt;T&gt; 用于将一个对象与另一个相同类型的对象进行比较。

否则,如果您想使用IEqualityComparer&lt;T&gt;,则应将其传递给Distinct() 方法。

// better to extend off of EqualityComparer<T> instead of
//     implementing IEqualityComparer<T> directly
public class NetComparer : EqualityComparer<Net>
{
    public override bool Equals(Net x, Net y)
    {
        return (x.Id == y.Id && x.Name == y.Name);
    }

    public override int GetHashCode(Net obj)
    {
        return obj.Id.GetHashCode() ^ obj.Name.GetHashCode();
    }
}

inputNetsA = inputNetsA.Distinct(new NetComparer()).ToList();

【讨论】:

  • 非常感谢。我在这条线上得到了 NullReference return obj.Id.GetHashCode() ^ obj.Name.GetHashCode();
  • GetHashCode中只返回null可以吗?
  • GetHashCode()的返回类型为int,不能返回null。我真正能说的是,返回适合该类型的任何内容。如果用于生成哈希码的对象的成员之一可以是null,那么它可能不是一个合适的键?否则,您需要决定处理它们的方法。例如,将它们视为0
  • 最好从EqualityComparer&lt;T&gt; 扩展而不是直接实现IEqualityComparer&lt;T&gt; 有什么好处?没听说过,到底接口有两个方法,EqualityComparer&lt;T&gt;有两个抽象方法(都是一样的)...
  • @JeffMercado 忽略它...看到您的其他回复...stackoverflow.com/a/5707968/613130。该类通过调用泛型(可重载)版本来实现非泛型版本。
猜你喜欢
  • 2023-01-31
  • 1970-01-01
  • 2010-09-30
  • 1970-01-01
  • 2018-11-25
  • 1970-01-01
  • 1970-01-01
  • 2011-03-13
  • 1970-01-01
相关资源
最近更新 更多