c# - Distinct() 返回具有用户定义类型的重复项

标签 c# linq

我正在尝试编写一个 Linq 查询,它返回一个对象数组,在它们的构造函数中具有唯一值。对于整数类型,Distinct 只返回每个值的一个副本,但是当我尝试创建我的对象列表时,事情就分崩离析了。我怀疑这是我类(class)的相等运算符的问题,但当我设置断点时,它永远不会命中。

过滤掉子表达式中重复的 int 解决了这个问题,也让我免于构造将立即被丢弃的对象,但我很好奇为什么这个版本不起作用。

更新:晚上 11:04 一些人指出 MyType 不会覆盖 GetHashCode()。恐怕我过于简化了这个例子。原来的 MyType 确实实现了它。我在下面添加了它,仅修改为在返回之前将哈希码放入临时变量中。

通过调试器运行,我看到 GetHashCode 的所有五次调用都返回了不同的值。由于 MyType 仅继承自 Object,因此这大概是 Object 会表现出的相同行为。

那么我得出的结论是哈希值应该基于 Value 的内容是否正确?这是我第一次尝试覆盖运算符,当时,似乎 GetHashCode 不需要特别花哨。 (这是我的平等检查第一次似乎没有正常工作。)

class Program
{
    static void Main(string[] args)
    {
        int[] list = { 1, 3, 4, 4, 5 };
        int[] list2 =
            (from value in list
             select value).Distinct().ToArray();    // One copy of each value.
        MyType[] distinct =
            (from value in list
             select new MyType(value)).Distinct().ToArray(); // Two objects created with 4.

        Array.ForEach(distinct, value => Console.WriteLine(value));
    }
}

class MyType
{
    public int Value { get; private set; }

    public MyType(int arg)
    {
        Value = arg;
    }

    public override int GetHashCode()
    {
        int retval = base.GetHashCode();
        return retval;
    }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;

        MyType rhs = obj as MyType;
        if ((Object)rhs == null)
            return false;

        return this == rhs;
    }

    public static bool operator ==(MyType lhs, MyType rhs)
    {
        bool result;

        if ((Object)lhs != null && (Object)rhs != null)
            result = lhs.Value == rhs.Value;
        else
            result = (Object)lhs == (Object)rhs;

        return result;
    }

    public static bool operator !=(MyType lhs, MyType rhs)
    {
        return !(lhs == rhs);
    }
}

最佳答案

您需要在您的类中覆盖 GetHashCode()。 GetHashCode 必须与 Equals 重载一起实现。代码在调用 Equals 之前检查哈希码是否相等是很常见的。这就是为什么您的 Equals 实现没有被调用的原因。

关于c# - Distinct() 返回具有用户定义类型的重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4309006/

相关文章:

c# - 将带有参数的 url 路由到 .NET 应用程序

C# - 如果列表包含列表

c# - 使用 Linq 对 Gridview 进行分页

c# - 选择 distinct 而不创建 IEqualityComparer

c# - 新的 Outlook.ItemEvents_10_ReplyEventHandler(MailItem_Reply) - 没有发件人电子邮件详细信息

c# - WPF和WinForms Dispatcher应该统一吗?

c# - Entity Framework LINQ 多对多查询

c# - 如何使用 Spreadsheet Gear C# 将 IRange 中所有日期格式的单元格转换为 DateTime?

c# - 通过 Web API 使用 Entity Framework 进行分页

c# - 在 linq 查询中创建某种循环