一 創建物件時考慮實作比較器
假設有這樣的場景,有一個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.uj5u.com/net/500378.html
標籤:.NET技术
