C# Linq 注意事项
Linq 中, GroupBy 之后 OrderBy
GroupBy().OrderBy() 是对 Key 进行的排序,所以想要对每组内的 Value 进行排序,需要 Foreach 之内对每个 Group 进行 OrderBy。
代码示例
using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApplication1 { internal class Program { static DateTime ParseDate(string date) { DateTime.TryParse(date, out var d); return d; } public static void Main(string[] args) { var students = new List<Student> { new Student { Info = new Info(){Name = "Alice", Score = 90, Date = ParseDate("9/14/2023 10:10:00 AM")}}, new Student { Info = new Info(){Name = "Bob", Score = 85 , Date = ParseDate("9/14/2023 10:20:00 AM")}}, new Student { Info = new Info(){Name = "Charlie", Score = 95 , Date = ParseDate("9/14/2023 10:12:00 AM")}}, new Student { Info = new Info(){Name = "David", Score = 85 , Date = ParseDate("9/14/2023 10:13:00 AM")}}, new Student { Info = new Info(){Name = "Kiz", Score = 85 , Date = ParseDate("9/14/2023 10:30:00 AM")}}, new Student { Info = new Info(){Name = "Eve", Score = 92 , Date = ParseDate("9/14/2023 10:16:00 AM")}} }; // 使用 GroupBy() 方法按分数分组 var groupedStudents = students.GroupBy(student => student.Info.Score); // 对每个分组内的学生按分数降序排序,<b>这个结果只是在分组的排序,不是每个组内的排序</b> var sortedGroups = groupedStudents.OrderByDescending(group => group.Key); // 输出结果 Console.WriteLine($"不对结果进行时间排序:"); foreach (var group in sortedGroups.Where(t=>t.Key.Equals(85))) { Console.WriteLine($"分数: {group.Key}"); foreach (var student in group) { var info = student.Info; Console.WriteLine($" 学生姓名: {info.Name}, {info.Score}, {info.Date}"); } } // output: // 不对结果进行时间排序: // 分数: 85 // 学生姓名: Bob, 85, 9/14/2023 10:20:00 AM // 学生姓名: David, 85, 9/14/2023 10:13:00 AM // 学生姓名: Kiz, 85, 9/14/2023 10:30:00 AM Console.WriteLine($"{Environment.NewLine}对结果进行时间排序:"); foreach (var group in sortedGroups.Where(t=>t.Key.Equals(85))) { Console.WriteLine($"分数: {group.Key}"); foreach (var student in group.OrderByDescending(t => t.Info.Date)) { var info = student.Info; Console.WriteLine($" 学生姓名: {info.Name}, {info.Score}, {info.Date}"); } } // output: // 对结果进行时间排序: // 分数: 85 // 学生姓名: Kiz, 85, 9/14/2023 10:30:00 AM // 学生姓名: Bob, 85, 9/14/2023 10:20:00 AM // 学生姓名: David, 85, 9/14/2023 10:13:00 AM } } public class Student { public Info Info { get; set; } } public class Info { public string Name { get; set; } public int Score { get; set; } public DateTime Date { get; set; } } }
FirstOrDefault 下的 Default
查看 Linq 中的 FirstOrDefault 方法中,发现最后找不到结果会返回一个 default(T),而 default 在给定不同的类型时又初始化为不同的值,有时为 null,有时又有值。
如果这时在 FirstOrDefault().Value 情况下使用,假设 T 是一些可为 null 的类型时,就会报可恶的 NullPointException,所以得额外注意,虽然可以使用 ?.Value 来避免,但是“代码编辑器”又会出现难看的波浪线提示。
官网介绍:https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/default
代码示例
using System; using System.Collections.Generic; Console.WriteLine(default(KeyValuePair<string, string>)); // output: [, ] Console.WriteLine(default(System.Numerics.Complex)); // output: <0; 0> Console.WriteLine(default(System.Collections.Generic.List<int>) is null); // output: True Console.WriteLine(default(string) is null); // output: True Console.WriteLine(default(int)); // output: 0 Console.WriteLine(default(int?) is null); // output: True Console.WriteLine(default(object) is null); // output: True Console.WriteLine(default(object) is null); // output: True
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步