1. 引言
在 C# 中,我们常常需要对列表进行排序。对于简单类型,我们可以通过调用默认的比较方法(如 int.CompareTo()
)来实现排序。但是对于复杂类型,我们需要自定义比较方法。这就涉及到了委托的应用。本文将介绍如何使用 C# 中的比较委托对复杂类型列表进行排序。
2. 简单类型排序介绍
首先,我们来回顾一下对简单类型的排序方法。以 int 类型为例:
int[] numbers = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3 };
Array.Sort(numbers);
这段代码创建了一个整数数组,并使用了内置的 Array.Sort()
方法对数组进行排序。在排序的过程中,我们并没有指定比较方法,因为默认情况下,Sort()
方法会使用整数类型的默认比较方法 int.CompareTo()
进行排序。
3. 复杂类型排序介绍
3.1 对象列表排序
当我们需要对对象列表进行排序时,我们需要自定义比较方法。比如,下面的代码创建了一个 Person 类,并创建了一个 Person 类型的列表:
class Person
{
public string Name { get; set; }
public int Age { get; set: }
public double Height { get; set; }
}
List people = new List()
{
new Person() { Name = "Alice", Age = 25, Height = 1.65 },
new Person() { Name = "Bob", Age = 30, Height = 1.75 },
new Person() { Name = "Charlie", Age = 20, Height = 1.80 },
};
如果我们要按照年龄进行排序,我们可以编写如下的比较方法:
int CompareByAge(Person x, Person y)
{
return x.Age.CompareTo(y.Age);
}
然后,我们可以使用列表的 Sort()
方法进行排序:
people.Sort(CompareByAge);
此时,列表会按照年龄的顺序进行排序。
3.2 复杂类型嵌套排序
当我们需要对内部具有多个字段的复杂类型进行排序时,我们可以定义一个委托,将排序条件表示为委托。例如:
delegate TKey KeySelector<TKey, TValue>(TValue value);
这个委托表示一个键选择器,它使用一个值作为参数,并返回该值的键。
假设我们有一个 Person
类型的列表,每个人有一个 LastName
字段和一个 FirstName
字段。我们可以使用下面的委托将委托定义为根据姓和名进行排序:
KeySelector<string, Person> byFirstName = p => p.FirstName;
KeySelector<string, Person> byLastName = p => p.LastName;
现在,我们要按照姓和名字对人员进行排序,我们可以使用 List<T>.Sort()
重载方法,它接受一个比较器委托作为参数。以下是一个使用上述键选择器的示例:
people.Sort((x, y) => byLastName(x).CompareTo(byLastName(y)) != 0
? byLastName(x).CompareTo(byLastName(y))
: byFirstName(x).CompareTo(byFirstName(y)));
上面的代码比较复杂,但它的逻辑很清晰。它首先比较姓氏,如果两个姓氏相同,则比较名字。由于选定的值和排序条件均由委托确定,因此此方法可以扩展到任意类型的排序。
4. 使用比较委托进行排序
4.1 排序委托
为了使用比较委托排序,我们需要定义一个委托类型。在以下示例中,我们定义一个名为 Comparison<T>
的通用委托类型,它需要两个类型为 T
的参数,并返回一个 int
类型的值:
delegate int Comparison<T>(T x, T y);
此委托表示一个比较函数,其参数为两个值和一个结果,结果的符号表示两个参数的相对顺序。
4.2 委托使用
现在,我们可以使用 Comparison<T>
委托进行排序。
以下是一个使用比较委托进行排序的示例,它在 Person
类型的列表中使用委托对人年龄进行排序:
List<Person> people = new List<Person>()
{
new Person() { Name = "Alice", Age = 25, Height = 1.65 },
new Person() { Name = "Bob", Age = 30, Height = 1.75 },
new Person() { Name = "Charlie", Age = 20, Height = 1.80 },
};
Comparison<Person> compareAge = (x, y) => x.Age.CompareTo(y.Age);
people.Sort(compareAge);
在上面的示例中,我们首先创建了一个 Person
类型的列表。然后,我们定义了一个比较委托,该委托将比较人的年龄。最后,我们使用 List<T>.Sort()
方法并传递比较委托来对列表进行排序。
4.3 按多个字段排序
为了按多个字段排序,我们可以向比较委托添加一些额外的比较条件。以下是对类型为 Person
的列表按姓和名进行排序的示例:
Comparison<Person> compareName = (x, y) => x.LastName.CompareTo(y.LastName) != 0
? x.LastName.CompareTo(y.LastName)
: x.FirstName.CompareTo(y.FirstName);
people.Sort(compareName);
在上面的示例中,我们首先定义了一个比较条件,将比较人的姓和名。然后,我们使用 List<T>.Sort()
方法并传递比较委托来对列表进行排序。
5. 总结
本文介绍了如何使用 C# 中的比较委托对复杂类型列表进行排序。我们首先回顾了对简单类型的排序方法,然后介绍了如何对复杂类型进行排序。最后,我们介绍了如何使用比较委托进行排序,并讨论了如何使用比较委托对多个字段进行排序。