C#中OrderByDescending 是LINQ扩展方法之一

在C#中,OrderByDescending 是LINQ扩展方法之一,用于对集合中的元素按降序进行排序。下面我会详细解释它的用法、原理和应用场景。

基本语法

csharp 复制代码
// 基本语法
IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector
)

// 带比较器的重载
IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    IComparer<TKey> comparer
)

基本用法示例

1. 对数值排序

csharp 复制代码
using System;
using System.Linq;
using System.Collections.Generic;

var numbers = new List<int> { 5, 2, 8, 1, 9, 3 };

// 降序排序
var sortedNumbers = numbers.OrderByDescending(x => x);

Console.WriteLine(string.Join(", ", sortedNumbers));
// 输出: 9, 8, 5, 3, 2, 1

2. 对字符串排序

csharp 复制代码
var names = new List<string> { "Alice", "Bob", "Charlie", "David" };

// 按字母降序排序
var sortedNames = names.OrderByDescending(name => name);

Console.WriteLine(string.Join(", ", sortedNames));
// 输出: David, Charlie, Bob, Alice

// 按字符串长度降序排序
var sortedByLength = names.OrderByDescending(name => name.Length);
Console.WriteLine(string.Join(", ", sortedByLength));
// 输出: Charlie, Alice, David, Bob

3. 对自定义对象排序

csharp 复制代码
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public decimal Salary { get; set; }
}

var people = new List<Person>
{
    new Person { Name = "Alice", Age = 25, Salary = 50000 },
    new Person { Name = "Bob", Age = 30, Salary = 45000 },
    new Person { Name = "Charlie", Age = 22, Salary = 60000 }
};

// 按年龄降序排序
var byAge = people.OrderByDescending(p => p.Age);
foreach (var person in byAge)
{
    Console.WriteLine($"{person.Name}: {person.Age}");
}
// 输出:
// Bob: 30
// Alice: 25
// Charlie: 22

// 按薪资降序排序
var bySalary = people.OrderByDescending(p => p.Salary);
foreach (var person in bySalary)
{
    Console.WriteLine($"{person.Name}: {person.Salary:C}");
}
// 输出:
// Charlie: ¥60,000.00
// Alice: ¥50,000.00
// Bob: ¥45,000.00

高级用法

1. 使用自定义比较器

csharp 复制代码
// 自定义字符串比较器(忽略大小写)
var caseInsensitiveComparer = StringComparer.OrdinalIgnoreCase;

var names = new List<string> { "apple", "Banana", "CHERRY", "date" };

var sorted = names.OrderByDescending(x => x, caseInsensitiveComparer);
Console.WriteLine(string.Join(", ", sorted));
// 输出: date, CHERRY, Banana, apple

2. 复杂排序条件

csharp 复制代码
// 按多个条件排序(先按薪资降序,再按姓名升序)
var complexSort = people
    .OrderByDescending(p => p.Salary)
    .ThenBy(p => p.Name);

foreach (var person in complexSort)
{
    Console.WriteLine($"{person.Name}: {person.Salary}");
}

3. 结合其他LINQ操作

csharp 复制代码
var result = people
    .Where(p => p.Age > 20)                    // 过滤
    .OrderByDescending(p => p.Salary)          // 降序排序
    .Select(p => new { p.Name, p.Salary })     // 投影
    .Take(3);                                  // 取前3个

foreach (var item in result)
{
    Console.WriteLine($"{item.Name}: {item.Salary}");
}

性能特点

  • 延迟执行 : OrderByDescending 使用延迟执行,只有在枚举结果时才会进行排序
  • 稳定性: 排序是稳定的,相等元素的相对顺序保持不变
  • 时间复杂度: 通常使用快速排序算法,平均时间复杂度为 O(n log n)

与相关方法的比较

OrderByDescending vs OrderBy

csharp 复制代码
var numbers = new[] { 3, 1, 4, 1, 5, 9, 2 };

var ascending = numbers.OrderBy(x => x);        // 升序: 1, 1, 2, 3, 4, 5, 9
var descending = numbers.OrderByDescending(x => x); // 降序: 9, 5, 4, 3, 2, 1, 1

OrderByDescending vs ThenByDescending

csharp 复制代码
var people = new List<Person> { /* ... */ };

// 主要排序 + 次要排序
var sorted = people
    .OrderByDescending(p => p.Age)          // 先按年龄降序
    .ThenByDescending(p => p.Salary);       // 再按薪资降序

实际应用场景

1. 数据报表

csharp 复制代码
// 获取销售额最高的产品
var topProducts = products
    .OrderByDescending(p => p.Sales)
    .Take(10);

2. 排行榜系统

csharp 复制代码
// 游戏玩家分数排行榜
var leaderboard = players
    .OrderByDescending(p => p.Score)
    .ThenBy(p => p.LastPlayed)  // 分数相同时,按最近游戏时间排序
    .Take(100);

3. 价格筛选

csharp 复制代码
// 商品按价格从高到低显示
var expensiveFirst = products
    .Where(p => p.Category == "Electronics")
    .OrderByDescending(p => p.Price);

注意事项

  1. 空值处理: 如果排序键可能为null,需要考虑null值的排序行为
  2. 性能考虑: 对于大数据集,排序可能影响性能
  3. 文化敏感性 : 字符串排序时注意文化差异,可使用 StringComparer
csharp 复制代码
// 处理可能为null的情况
var sortedWithNulls = items.OrderByDescending(x => x.Property ?? defaultValue);

// 使用特定文化进行字符串排序
var cultureAware = strings.OrderByDescending(s => s, StringComparer.Create(
    System.Globalization.CultureInfo.CurrentCulture, false));

OrderByDescending 是LINQ中非常实用的排序方法,通过合理使用可以让数据处理更加简洁高效。

相关推荐
追逐时光者1 天前
一个致力于为 C# 程序员提供更佳的编码体验和效率的 Visual Studio 扩展插件
后端·c#·visual studio
molaifeng1 天前
Go 语言如何实现高性能网络 I/O:Netpoller 模型揭秘
开发语言·网络·golang
崇山峻岭之间1 天前
Matlab学习记录33
开发语言·学习·matlab
Evand J1 天前
【2026课题推荐】DOA定位——MUSIC算法进行多传感器协同目标定位。附MATLAB例程运行结果
开发语言·算法·matlab
jllllyuz1 天前
基于MATLAB的二维波场模拟程序(含PML边界条件)
开发语言·matlab
忆锦紫1 天前
图像增强算法:Gamma映射算法及MATLAB实现
开发语言·算法·matlab
SunflowerCoder1 天前
EF Core + PostgreSQL 配置表设计踩坑记录:从 23505 到 ChangeTracker 冲突
数据库·postgresql·c#·efcore
亲爱的非洲野猪1 天前
Java锁机制八股文
java·开发语言
LawrenceLan1 天前
Flutter 零基础入门(十二):枚举(enum)与状态管理的第一步
开发语言·前端·flutter·dart
charlie1145141911 天前
从 0 开始的机器学习——NumPy 线性代数部分
开发语言·人工智能·学习·线性代数·算法·机器学习·numpy