-
改善C#程序的方法-3 比较器和LINQ排序
一 创建对象时考虑实现比较器
假设有这样的场景,有一个40个人的学生列表,业务中需针对学生的成绩来进行排序。
可以考虑用IComparable接口和ICompare接口实现:
class Program { static void Main(string[] args) { var stus = new List<Student>(); stus.Add(new Student() { Name = "zhangsan", EnglishGrades = 80.5, MathGrades = 90 }); stus.Add(new Student() { Name = "lisi", EnglishGrades = 74, MathGrades = 91 }); stus.Add(new Student() { Name = "wangwu", EnglishGrades = 94, MathGrades = 85.5 }); stus.Add(new Student() { Name = "zhaoliu", EnglishGrades = 88.5, MathGrades = 86 }); stus.Sort(); Console.WriteLine("使用默认比较器排序:"); foreach (var stu in stus) { Console.WriteLine($"Name:{stu.Name},\tEnglish:{stu.EnglishGrades},\tMath:{stu.MathGrades}"); } stus.Sort(new MathComparer()); Console.WriteLine("使用自定义比较器排序:"); foreach (var stu in stus) { Console.WriteLine($"Name:{stu.Name},\tEnglish:{stu.EnglishGrades},\tMath:{stu.MathGrades}"); } Console.ReadLine(); } } //Student通过IComparable接口,实现默认比较器 class Student : IComparable<Student> { public string Name { get; set; } public double EnglishGrades { get; set; } public double MathGrades { get; set; } public int CompareTo(Student stu) { if (EnglishGrades > stu.EnglishGrades) { return 1; } else if (EnglishGrades == stu.EnglishGrades) { return 0; } else { return -1; } //return EnglishGrades.CompareTo(stu.EnglishGrades); double类型的默认比较方法 } } //通过IComparer接口实现自定义的比较器 class MathComparer : IComparer<Student> { public int Compare(Student x, Student y) { return x.MathGrades.CompareTo(y.MathGrades); } }
输出:
使用默认比较器排序: Name:lisi, English:74, Math:91 Name:zhangsan, English:80.5, Math:90 Name:zhaoliu, English:88.5, Math:86 Name:wangwu, English:94, Math:85.5 使用自定义比较器排序: Name:wangwu, English:94, Math:85.5 Name:zhaoliu, English:88.5, Math:86 Name:zhangsan, English:80.5, Math:90 Name:lisi, English:74, Math:91
二 使用LINQ取代集合中的比较器
上述的方法实现的排序存在2个问题:
- 可扩展性太低,如果存在新的排序要求,就必须实现新的比较器;
- 对代码的侵入性太高,为类型继承了接口,新增了方法。
LINQ提供了类似于SQL的语法来实现遍历、筛选和投影集合的强大功能,可以实现上述的排序要求。
static void Main(string[] args) { var stus = new List<Student>(); stus.Add(new Student() { Name = "zhangsan", EnglishGrades = 80.5, MathGrades = 90 }); stus.Add(new Student() { Name = "lisi", EnglishGrades = 74, MathGrades = 91 }); stus.Add(new Student() { Name = "wangwu", EnglishGrades = 94, MathGrades = 85.5 }); stus.Add(new Student() { Name = "zhaoliu", EnglishGrades = 88.5, MathGrades = 86 }); var orderByStus = from s in stus orderby s.EnglishGrades select s; //orderByStus = stus.OrderBy(s => s.EnglishGrades); foreach (var stu in orderByStus) { Console.WriteLine($"Name:{stu.Name},\tEnglish:{stu.EnglishGrades},\tMath:{stu.MathGrades}"); } Console.WriteLine(); orderByStus = from s in stus orderby s.MathGrades select s; //orderByStus = stus.OrderBy(s => s.MathGrades); foreach (var stu in orderByStus) { Console.WriteLine($"Name:{stu.Name},\tEnglish:{stu.EnglishGrades},\tMath:{stu.MathGrades}"); } Console.ReadLine(); }
LINQ此功能的实现本身是借助于FCL泛型集合的比较器、迭代器和索引器。LINQ封装了这些功能,让我们使用更加方便。
在命名空间System.Linq下的Enumerable方法中为泛型集合提供了很多扩展方法。
如排序中使用到的OrderBy方法:
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);
它为继承了IEnumerable<T>接口的集合提供排序的功能。
出处:https://www.cnblogs.com/wwwen/p/16524999.html
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数