C#中List<T>排序:5分钟从混乱到有序
\n\n想象一下:你有一个用户列表,需要按姓氏的字母顺序显示在屏幕上。或者一个商品列表——按价格从低到高排序。熟悉的任务吗?在Stack Overflow上,“How to Sort a List<T> by a property in the object” 问题获得了数千次浏览——这意味着这个话题困扰着许多开发者。
\n\n在本文中,我们将介绍在C#中对列表进行排序的五种方法。你将学习如何按单个属性、多个字段进行排序,以及如何使排序尽可能快。开始吧!
\n\n我们要排序什么:User类
\n\n作为示例,我们采用一个简单的数据模型——包含姓名、年龄和评分的用户。
\n\npublic class User\n{\n public string Name { get; set; }\n public int Age { get; set; }\n public double Rating { get; set; }\n\n public override string ToString()\n {\n return $"{Name} ({Age}) — {Rating:F2}";\n }\n}\n\n创建一个测试列表:
\n\nList<User> users = new List<User>\n{\n new User { Name = "安娜", Age = 30, Rating = 4.5 },\n new User { Name = "鲍里斯", Age = 25, Rating = 3.8 },\n new User { Name = "维克多", Age = 35, Rating = 4.9 },\n new User { Name = "加林娜", Age = 28, Rating = 4.2 }\n};\n\n方法1:LINQ OrderBy——最简单且优雅
\n\n如果你想按对象属性对List<T>进行排序,快速且无需额外代码——使用LINQ。OrderBy方法创建一个新的有序序列,而不修改原始列表。这在需要“即时”排序时非常理想。
// 按姓名排序(升序)\nvar sortedByName = users.OrderBy(u => u.Name).ToList();\n\n// 按年龄排序(降序)\nvar sortedByAgeDesc = users.OrderByDescending(u => u.Age).ToList();\n\n// 按多个字段排序:先按年龄,再按评分\nvar sortedMulti = users\n .OrderBy(u => u.Age)\n .ThenBy(u => u.Rating)\n .ToList();\n\n优点:可读性强,支持排序链,适用于任何属性类型。
\n缺点:创建新列表(额外内存)。
方法2:使用Comparison委托的List.Sort——原地排序
\n\n如果需要对C#列表进行排序而不创建副本(节省内存),请使用带有lambda表达式的Sort方法。此方法会修改原始集合。
// 按姓名排序(原地)\nusers.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal));\n\n// 按年龄排序(降序)\nusers.Sort((a, b) => b.Age.CompareTo(a.Age));\n\n// 按评分排序\nusers.Sort((a, b) => a.Rating.CompareTo(b.Rating));\n\n优点:不创建新对象,对于大列表更快。
\n缺点:复杂排序时可读性较差。
方法3:实现IComparable——开箱即用的排序
\n\n如果你的类总是应该按同一个字段排序(例如按姓名),请实现IComparable<T>接口。这样,List.Sort()无需参数即可工作。
public class User : IComparable<User>\n{\n // ... 上面示例中的属性 ...\n\n public int CompareTo(User other)\n {\n if (other == null) return 1;\n return string.Compare(this.Name, other.Name, StringComparison.Ordinal);\n }\n}\n\n// 使用\nusers.Sort(); // 自动按姓名排序\n\n优点:业务逻辑的自然排序。
\n缺点:硬编码一个规则——对于其他字段需要编写单独的逻辑。