c# - 如何使用 IComparable 和 IComparer 对对象列表进行排序

标签 c# list sorting icomparable icomparer

我正在尝试实现此链接的相同示例,但更注重受抚养 child 的数量。

http://www.codeproject.com/Articles/42839/Sorting-Lists-using-IComparable-and-IComparer-Inte

所以我有 3 名员工,分别为 A: 0、B: 0、C: 2。我想按 child 的数量对它们进行降序排列。所以我会有 C:2、B:0、A:0

但我的列表尚未排序。仍为 A: 0、B: 0、C: 2

我做错了什么?

我的比较器

public class EmployeeComparer : IComparer<Employee>
{
    public int Compare(Employee x, Employee y)
    {
        this.CompareNumberOfKids(x, y);
    }

    public int CompareNumberOfKids(Employee x, Employee y)
    {
        if (x.NumberOfKids > y.NumberOfKids)
        {
            return -1;
        }
        else if (x.NumberOfKids < y.NumberOfKids)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
}

我的业务实体

public class Employee : IComparable<Employee>
{
    //...//
    Public NumberOfKids { get; set; }

    int IComparable<Employee>.CompareTo(Employee next)
    {
        return new EmployeeComparer().Compare(this, next);
    }

    public override bool Equals(object obj)
    {
        if (obj != null && obj is Emmployee)
        {
            return ((Employee)obj).ID.Equals(this.ID);
        }
        else return base.Equals(obj);
    }

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

Aspx.cs

public List<Employee> GetEmployeeSortedList()
{
    List<Employee> list = new List<Employee>();
    list.Add(new Employee() { Name = "A", NumberOfKids = 0 } );
    list.Add(new Employee() { Name = "B", NumberOfKids = 0 } );
    list.Add(new Employee() { Name = "C", NumberOfKids = 2 } );
    list.Add(new Employee() { Name = "D", NumberOfKids = 1 } );
    list.Add(new Employee() { Name = "E", NumberOfKids = 0 } );
    list.Add(new Employee() { Name = "F", NumberOfKids = 4 } );

    list = list.Take(3).ToList();
    EmployeeComparer comp = new EmployeeComparer();
    list.Sort(comp);
    return list;
}

最佳答案

首先,不需要 IComparer<Employee>如果您的 Employee 按降序排序类实现IComparable<Employee>使用相同的排序标准。这对你的 Employee 来说效率极其低下。类来实例化一个新的 IComparer<Employee>每次比较。

您应该更改您的Employee类,使其 CompareTo看起来像这样:

int CompareTo(Employee next)
{
    return next.NumberOfKids.CompareTo(this.NumberOfKids);
}

然后你就可以放弃 EmployeeComparer总共并按如下方式排序:

list = list.Take(3).ToList();
list.Sort();  // Uses default IComparable for the Employee class
return list;

通常,您会创建 IComparable<T>类的实现执行默认的排序顺序。对于员工来说,可能是员工 ID,也可能是姓氏、名字。 IComparer<T>实现应该适用于其他排序标准。

List<T>不过,您还有另一种选择:使用匿名函数。例如,您可以通过编写以下内容来做到这一点:

list.Sort((x, y) => y.NumberOfKids.CompareTo(x.NumberOfKids));

参见this List.Sort overload .

或者,您可以放弃 IComparer<T> 的整个想法和IComparable<T>List.Sort完全以 LINQ 方式完成:

var result = list.Take(3).OrderByDescending(x => x.NumberOfKids).ToList();

关于c# - 如何使用 IComparable 和 IComparer 对对象列表进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26868600/

相关文章:

python - 从 Python 中的元组列表中迭代查找/替换

list - 悬停时是否可以更改嵌套列表的颜色?

arrays - 在 Julia 中按多个键对 Dict 数组进行排序

c# - 线段的多边形

c# - 这个 'double +=' 线程安全吗?

c# - 15 秒后自动隐藏 C# 中的 ViewBag 消息

r - 在 R 中查找列表中的子列表

java - 删除重复 JAVA 数组的最佳实现

bash - du 仅查看目录并按大小排序

c# - 以编程方式设置 Active Directory 密码时,如何要求更改密码?