C# 创建对象时需要考虑是否实现比较器

创建对象,有时候需要比较排序输出,例如一个Salary列表,可以支持针对基本工资来罗列,也可以针对奖金来罗列,这个时候就要用到IComparable接口和IComparer接口:

 1     //IComparable:比较当前对象和同一类型的另一对象。
 2     class Salary : IComparable<Salary>
 3     {
 4         public string Name { get; set; }
 5         public int BaseSalary { get; set; }
 6         public int Bonus { get; set; }
 7 
 8         //实现IComparable接口的默认比较器,比较BaseSalary
 9         public int CompareTo(Salary other)
10         {
11             return BaseSalary.CompareTo(other.BaseSalary);
12         }
13     }
14 
15     //IComparer:定义类型为比较两个对象而实现的方法。
16     class BonusComparer : IComparer<Salary>
17     {
18         //实现IComparer接口的非默认比较器,比较Bonus
19         public int Compare(Salary s1, Salary s2)
20         {
21             return s1.Bonus.CompareTo(s2.Bonus);
22         }
23     }

Salary类继承了IComparable接口,实现了IComparable的成员CompareTo方法,比较不同对象的BaseSalary;BonusComparer类继承IComparer接口,实现了IComparer的成员Compare方法,比较两个Salary对象的Bonus。(使用泛型,可以避免运行时转型对性能的影响)。

实现了IComparable接口,就可以对Salary列表进行排序了:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             List<Salary> companySalary = new List<Salary>() 
 6             {
 7                 new Salary(){Name="Mike", BaseSalary=3000,Bonus=1000},
 8                 new Salary(){Name="Rose", BaseSalary=2000,Bonus=4000},
 9                 new Salary(){Name="Jeffry", BaseSalary=1000,Bonus=6000},
10                 new Salary(){Name="Steve", BaseSalary=4000,Bonus=3000},
11             };
12 
13             Console.WriteLine("初始排序:");
14             foreach (Salary item in companySalary)
15             {
16                 Console.WriteLine(String.Format("Name:{0}\tBaseSaraly:{1}\tBonus:{2}", item.Name, item.BaseSalary, item.Bonus));
17             }
18 
19             companySalary.Sort();//默认比较器排序
20             Console.WriteLine("默认比较器排序(按BaseSalary):");
21             foreach (Salary item in companySalary)
22             {
23                 Console.WriteLine(String.Format("Name:{0}\tBaseSaraly:{1}\tBonus:{2}", item.Name, item.BaseSalary, item.Bonus));
24             }
25 
26             companySalary.Sort(new BonusComparer());//提供一个非默认比较器
27             Console.WriteLine("非默认比较器排序(按Bonus):");
28             foreach (Salary item in companySalary)
29             {
30                 Console.WriteLine(String.Format("Name:{0}\tBaseSaraly:{1}\tBonus:{2}", item.Name, item.BaseSalary, item.Bonus));
31             }
32             Console.Read();
33         }
34     }

输出结果:

初始排序,按初始化时的添加顺序输出结果;默认比较器排序,调用Sort方法对Salary列表排序,默认是按BaseSalary从小到大排;非默认比较器排序,给Sort方法提供了BonusComparer类的比较方法,按Bonus从小到大排序。


 

可以使用LINQ查询简化代码:

 1 class Program
 2 {
 3     static void Main(string[] args)
 4     {
 5         List<Salary> companySalary = new List<Salary>()
 6         {
 7             new Salary(){Name="Mike", BaseSalary=3000,Bonus=1000},
 8             new Salary(){Name="Rose", BaseSalary=2000,Bonus=4000},
 9             new Salary(){Name="Jeffry", BaseSalary=1000,Bonus=6000},
10             new Salary(){Name="Steve", BaseSalary=4000,Bonus=3000},
11         };
12 
13         Console.WriteLine("初始排序:");
14         foreach (Salary item in companySalary)
15         {
16             Console.WriteLine(String.Format("Name:{0}\tBaseSaraly:{1}\tBonus:{2}", item.Name, item.BaseSalary, item.Bonus));
17         }
18 
19         Console.WriteLine("LINQ排序(按BaseSalary):");
20         var orderByBaseSalary = from cs in companySalary
21                                 orderby cs.BaseSalary
22                                 select cs;
23         foreach (Salary item in orderByBaseSalary)
24         {
25             Console.WriteLine(String.Format("Name:{0}\tBaseSaraly:{1}\tBonus:{2}", item.Name, item.BaseSalary, item.Bonus));
26         }
27 
28         Console.WriteLine("LINQ排序(按Bonus):");
29         var orderBonus = from cs in companySalary
30                          orderby cs.Bonus
31                          select cs;
32         foreach (Salary item in orderBonus)
33         {
34             Console.WriteLine(String.Format("Name:{0}\tBaseSaraly:{1}\tBonus:{2}", item.Name, item.BaseSalary, item.Bonus));
35         }
36         Console.Read();
37     }
38 }
39 class Salary 
40 {
41     public string Name { get; set; }
42     public int BaseSalary { get; set; }
43     public int Bonus { get; set; }
44 }

输出结果与使用比较器的一致:

LINQ查询的实现,也是借助了FCL泛型集合的比较器、迭代器、索引器,LINQ相当于封装了这些功能,使用起来更方便。

 

参考:《编写高质量代码改善C#程序的157个建议》陆敏技

posted @ 2020-06-20 10:54  XXXUJIA  阅读(241)  评论(0编辑  收藏  举报