C#基础:通过委托给任何对象数组进行排序
在日常编写程序的时候,我们需要对一些对象进行排序,比如对int数组进行排序,自定义类数组进行排序,首先我们先讨论对数组进行排序,我们应该对冒泡排序比较熟悉,下面是数组用冒泡排序的方法
for (int i = 0; i < sortArry.Length; i++) { for (int j = sortArry.Length - 1; j > i; j--) { if (sortArry[i] < sortArry[j]) { int temp = sortArry[i]; sortArry[i] = sortArry[j]; sortArry[j] = temp; } } }
上面这段代码非常适用于int型数组排序,但是如果我们希望对任何对象排序应该怎么办?如果我们定义了一个自定义实体类数组,我们需要对这个实体类的对象进行排序,我们就不能用sortArry[i] < sortArry[j]的方法来进行排序了,但是我们仔细想一想,自定义类默认情况下是不能用“<”运算符进行比较的。接下来我要说的就是,虽然不能直接用比较运算符进行比较,但是我们可以在类里面实现用某一字段的比较来实现对象与对象之间的比较。
下面的例子我们创建了一个Employee类,类里面顶一个通过比较Salary的方法来进行Employee对象与对象之间的比较。在类Objectsort中,我们用泛型方法sort<T>来实现冒泡排序,这里为什么用泛型,大家应该都懂,为了确保类型安全。然后我们用Func<T,T,bool>引用方法。该委托的签名带有两个传入参数且返回值为Bool。
下面就是具体的例子:
using System; using System.Collections.Generic; namespace ConsoleSort { #region 客户端 class Program { static void Main(string[] args) { //实体化雇员 Employee[] employees = { new Employee("张三",5000), new Employee("李四",4000), new Employee("王五",4500), new Employee("赵六",5640), new Employee("李七",1000) }; /*将雇员实体传入排序类(ObjectSort)的排序方法(Sort)*/ /*并传入和(Func<T, T, bool>)委托匹配签名的方法(Employee.compareBysalary)*/ ObjectSort.Sort<Employee>(employees, Employee.compareBysalary); foreach (var em in employees) { Console.WriteLine(em.ToString());//输出排序后的结果 } } } #endregion #region 对象排序类 sealed class ObjectSort { /// <summary> /// 定义Sort<T>方法,此处用的排序为冒泡排序,此方法可以对任何对象排序 /// 此处使用泛型的原因是保证类型安全 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="sortArray">传入排序的对象</param> /// <param name="comparison"></param> public static void Sort<T>(IList<T> sortArray, Func<T, T, bool> comparison) { for (int i = 0; i < sortArray.Count-1; i++) { for (int j = sortArray.Count-1; j > i; j--) { if(comparison(sortArray[i],sortArray[j])) { T temp=sortArray[i]; sortArray[i]=sortArray[j]; sortArray[j]=temp; } } } } } #endregion #region 雇员实体类 sealed class Employee { /// <summary> /// 构造函数 /// </summary> /// <param name="name"></param> /// <param name="salary"></param> public Employee(string name, decimal salary) { this.Name = name; this.Salary = salary; } public string Name{get;set;} public decimal Salary{get;set;} /// <summary> /// 重写雇员信息的输出方式 /// </summary> /// <returns></returns> public override string ToString() { return string.Format("{0}:{1:C}", Name, Salary); } /// <summary> /// Employee类中匹配Func<T,T,bool>的签名,通过雇员的工资进行比较 /// </summary> /// <param name="em1"></param> /// <param name="em2"></param> /// <returns></returns> public static bool compareBysalary(Employee em1, Employee em2) { return em1.Salary >em2.Salary; } } #endregion }