ZetCode

C# IComparable

最后修改日期 2024 年 1 月 22 日

在本文中,我们将展示如何使用 IComparable 接口在 C# 中比较值。

C# IComparable 接口

IComparable 接口定义了一个通用的、特定于类型的比较方法,值类型或类实现该方法来对它们的实例进行排序。

IComparable 由可以排序或分类的类型实现。 该接口要求实现 CompareTo 方法。 实现的方法会被诸如 Array.SortList.Sort 之类的方法自动调用。

该接口由程序员可以控制的类型使用;换句话说,就是程序员编写的代码。 如果代码由其他人提供,我们使用 IComparer 接口代替。

C# IComparable 示例

在下面的示例中,我们对一个员工列表进行排序。

Program.cs
List<Employee> employees =
[
    new ("John Doe", 1230),
    new ("Lucy Novak", 670),
    new ("Robin Brown",2300),
    new ("Joe Draker", 1190),
    new ("Janet Doe", 980)
];

employees.Sort();
employees.ForEach(Console.WriteLine);

Console.WriteLine("---------------------------");

employees.Reverse();
employees.ForEach(Console.WriteLine);

record Employee(string Name, int Salary) : IComparable<Employee>
{
    public int CompareTo(Employee? other)
    {
        if (other == null) return 1;
        // return other.Salary.CompareTo(Salary);
        if (Salary < other.Salary)
        {
            return 1;
        }
        else if (Salary > other.Salary)
        {
            return -1;
        }
        else
        {
            return 0;
        }
    }
}

在该示例中,我们提供了 Employee 类的 CompareTo 方法的实现。 该类实现了 IComparable 接口。

public int CompareTo(Employee? other)
{
    if (other == null) return 1;
    // return other.Salary.CompareTo(Salary);
    if (Salary < other.Salary)
    {
        return 1;
    }
    else if (Salary > other.Salary)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

CompareTo 方法的实现将按工资对员工进行排序。

if (other == null) return 1;

按照通用定义,当前对象大于 null

employees.Sort();

我们对列表进行排序。 该方法在排序时会考虑已实现的 CompareTo 方法。

employees.Reverse();

我们以相反的顺序对列表进行排序。

$ dotnet run
Employee { Name = Robin Brown, Salary = 2300 }
Employee { Name = John Doe, Salary = 1230 }
Employee { Name = Joe Draker, Salary = 1190 }
Employee { Name = Janet Doe, Salary = 980 }
Employee { Name = Lucy Novak, Salary = 670 }
---------------------------
Employee { Name = Lucy Novak, Salary = 670 }
Employee { Name = Janet Doe, Salary = 980 }
Employee { Name = Joe Draker, Salary = 1190 }
Employee { Name = John Doe, Salary = 1230 }
Employee { Name = Robin Brown, Salary = 2300 }

C# IComparable 示例 II

在以下示例中,我们对一个用户数组进行排序。

Program.cs
User[] users =
[
    new ("Robin", "bookseller"),
    new ("John", "gardener"),
    new ("John", "writer"),
    new ("Janet", "teacher"),
    new ("Andrew", "driver"),
    new ("Lucy", "accountant")
];

Array.Sort(users);

foreach (var user in users)
{
    Console.WriteLine(user);
}

Console.WriteLine("------------------------------");

Array.Reverse(users);

foreach (var user in users)
{
    Console.WriteLine(user);
}

record User(string Name, string Occupation) : IComparable<User>
{
    public int CompareTo(User? other)
    {
        if (other == null) return 1;
        return Occupation.CompareTo(other.Occupation);
    }
}

该示例以升序和降序对用户数组进行排序。

public int CompareTo(User? other)
{
    if (other == null) return 1;
    return Occupation.CompareTo(other.Occupation);
}

该方法按职业排序。

Array.Sort(users);

我们按升序对用户进行排序。

Array.Reverse(users);

我们按降序对用户进行排序。

$ dotnet run
User { Name = Lucy, Occupation = accountant }
User { Name = Robin, Occupation = bookseller }
User { Name = Andrew, Occupation = driver }
User { Name = John, Occupation = gardener }
User { Name = Janet, Occupation = teacher }
User { Name = John, Occupation = writer }
------------------------------
User { name = John, Occupation = writer }
User { name = Janet, Occupation = teacher }
User { name = John, Occupation = gardener }
User { name = Andrew, Occupation = driver }
User { name = Robin, Occupation = bookseller }
User { name = Lucy, Occupation = accountant }

C# IComparable 多个字段

在以下示例中,我们通过两个字段进行比较。

Program.cs
List<User> users =
[
    new ("Robin", "bookseller"),
    new ("Simon", "teacher"),
    new ("Arnold", "teacher"),
    new ("John", "gardener"),
    new ("Adam", "gardener"),
    new ("Peter", "gardener"),
    new ("John", "writer"),
    new ("Janet", "teacher"),
    new ("Andrew", "driver"),
    new ("Lucy", "accountant"),
    new ("Michael", "teacher")
];

users.Sort();

foreach (var user in users)
{
    Console.WriteLine(user);
}

record User(string Name, string Occupation) : IComparable<User>
{
    public int CompareTo(User? other)
    {
        if (other == null) return 1;
        int res = Occupation.CompareTo(other.Occupation);

        if (res == 0)
        {
            res = other.Name.CompareTo(Name);
        }

        return res;
    }
}

我们有一些职业相同的用户。 在这种情况下,我们将比较他们的名字。

public int CompareTo(User? other)
{
    if (other == null) return 1;
    int res = Occupation.CompareTo(other.Occupation);

    if (res == 0)
    {
        res = other.Name.CompareTo(Name);
    }

    return res;
}

首先,我们按 Occupation 字段比较用户。 如果它们相等,则比较它们的 Name 字段。 我们比较名称的方式会导致降序排序。

$ dotnet run 
User { Name = Lucy, Occupation = accountant }
User { Name = Robin, Occupation = bookseller }
User { Name = Andrew, Occupation = driver }
User { Name = Peter, Occupation = gardener }
User { Name = John, Occupation = gardener }
User { Name = Adam, Occupation = gardener }
User { Name = Simon, Occupation = teacher }
User { Name = Michael, Occupation = teacher }
User { Name = Janet, Occupation = teacher }
User { Name = Arnold, Occupation = teacher }
User { Name = John, Occupation = writer }

来源

IComparable 接口

在本文中,我们使用了 IComparable 接口来对 C# 中的数据进行排序。

作者

我的名字是 Jan Bodnar,我是一位充满激情的程序员,拥有丰富的编程经验。 我自 2007 年以来一直在撰写编程文章。到目前为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 C# 教程