如何正确使用distinct和compare



我用distinct表示

使用默认值从序列返回不同的元素相等比较器用于比较值。

然而,当我运行这段代码时,我得到了多个相同的id

        var ls = ls2.Distinct().OrderByDescending(s => s.id);
        foreach (var v in ls)
        {
            Console.WriteLine(v.id);
        }

我在我的类中实现了这些,但这仍然不起作用

class Post : IComparable<Post>, IEqualityComparer<Post>, IComparer<Post>

我是这样实现的

                int IComparable<Post>.CompareTo(Post other)
                {
                    return (int)(id - other.id);
                }
                bool IEqualityComparer<Post>.Equals(Post x, Post y)
                {
                    return x.id == y.id;
                }
                int IEqualityComparer<Post>.GetHashCode(Post obj)
                {
                    throw new NotImplementedException();
                }
                int IComparer<Post>.Compare(Post x, Post y)
                {
                    return (int)(x.id - y.id);
                }

您应该实现GetHashCode()

既然您委托给-==,为什么不直接委托给id中的适当功能呢?ie。id.Compare(other.id)obj.id.GetHashCode(),并将比较器委托给Compare。并实现IEquatable

            int IComparable<Post>.CompareTo(Post other)
            {
                return id.Compare(other.id);
            }
            bool IEquatable<Post>.Equals(Post x)
            {
                return id == y.id;
            }

            bool IEqualityComparer<Post>.Equals(Post x, Post y)
            {
                return x.Equals(y.id);
            }
            int IEqualityComparer<Post>.GetHashCode(Post obj)
            {
                return obj.id.GetHashCode(); 
            }
            int IComparer<Post>.Compare(Post x, Post y)
            {
                return x.Compare(y);
            }

这里假设id是int型,如果不是,那么你也可以为id实现这些。

您需要在比较器中正确实现GetHashCode() -在您的情况下,您可以只返回id的哈希码:

int IEqualityComparer<Post>.GetHashCode(Post obj)
{
   return obj.id.GetHashCode();
}

也正如@dash在评论中指出的那样,如果你选择走那条路(选项1),你需要在Post中实现IEquatable<T>

比较器应该在一个单独的类中实现,然后你可以在一个Distinct()重载中传递(选项2),即在你的情况下可以是MyPostComparer类:

var ls = ls2.Distinct(new MyPostComparer()).OrderByDescending(s => s.id);

第三种选择是使用MoreLinq项目的DistinctBy()方法。

最新更新