c# - 如何使用 IEqualityComparer

标签 c# linq iequalitycomparer

我的数据库中有一些相同编号的铃铛。我想得到所有这些而不重复。我创建了一个比较类来完成这项工作,但是该函数的执行导致没有 distinct 的函数出现很大的延迟,从 0.6 秒到 3.2 秒!

我做得对还是必须使用其他方法?

reg.AddRange(
    (from a in this.dataContext.reglements
     join b in this.dataContext.Clients on a.Id_client equals b.Id
     where a.date_v <= datefin && a.date_v >= datedeb
     where a.Id_client == b.Id
     orderby a.date_v descending 
     select new Class_reglement
     {
         nom  = b.Nom,
         code = b.code,
         Numf = a.Numf,
     })
    .AsEnumerable()
    .Distinct(new Compare())
    .ToList());

class Compare : IEqualityComparer<Class_reglement>
{
    public bool Equals(Class_reglement x, Class_reglement y)
    {
        if (x.Numf == y.Numf)
        {
            return true;
        }
        else { return false; }
    }
    public int GetHashCode(Class_reglement codeh)
    {
        return 0;
    }
}

最佳答案

您的 GetHashCode 实现总是返回相同的值。 Distinct 依靠良好的哈希函数来高效工作,因为它在内部构建了一个 hash table .

在实现类的接口(interface)时,阅读 documentation 很重要,了解您应该实现哪个契约(Contract)。1

在您的代码中,解决方案是将 GetHashCode 转发给 Class_reglement.Numf.GetHashCode 并在那里适本地实现它。

除此之外,您的 Equals 方法充满了不必要的代码。它可以重写如下(相同的语义,1/4 的代码,更具可读性):

public bool Equals(Class_reglement x, Class_reglement y)
{
    return x.Numf == y.Numf;
}

最后,ToList 调用是不必要且耗时的:AddRange 接受任何 IEnumerable,因此转换为 List 不是必需的。 AsEnumerable 在这里也是多余的,因为在 AddRange 中处理结果无论如何都会导致这种情况。


1 在不知道代码实际做什么的情况下编写代码称为 cargo cult programming .这是一种令人惊讶的普遍做法。它根本不起作用。

关于c# - 如何使用 IEqualityComparer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6694508/

相关文章:

c# - ASP .NET MVC3 ViewBag 清理字符串

c# - 如何使文本框自动完成结果选择直接导航到记录详细信息?

c# - C# Linq 中的日期格式

c# - 返回匿名类型的 IEnumerable

C# - List<T>.Remove() 总是删除列表中的第一个对象

c# - 在本地时区格式化 UTC 时间戳

c# - VirtualizingStackPanel 和 TextWrapping 错误? Windows Mobile

.net - Linq to SQL中是否提供Unpivot(非枢轴)功能?如何?

.net - LINQ to Entities 无法识别“Boolean Contains”方法

c# - 可以改进 IEqualityComparer 的实现吗?