ToB企服应用市场:ToB评测及商务社交产业平台
标题:
改善C#程序的方法-(3)比较器和LINQ排序
[打印本页]
作者:
三尺非寒
时间:
2022-9-2 15:15
标题:
改善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接口的集合提供排序的功能。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4