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中非常实用的排序方法,通过合理使用可以让数据处理更加简洁高效。

相关推荐
瑞雪兆丰年兮7 分钟前
JavaWeb-day14-SpringBootWeb原理篇
java·开发语言·spring boot·spring·bean·mybatis·javaweb
SomeOtherTime2 小时前
Rust生命周期介绍(AI回答)
开发语言·后端·rust
程序猿打工仔2 小时前
计算机基础(C语言)考编、专技岗
c语言·开发语言·算法
喵本喵叁肆2 小时前
Rényi 差分隐私:把隐私损失看成一族矩(英文原题:Rényi Differential Privacy (CSF 2017))
开发语言·r语言
Hvitur3 小时前
Java - Lambda
java·开发语言·python
xiaoye-duck3 小时前
《C++ 项目:手写大模型接入 SDK》DataManager数据管理模块:SQLite持久化存储
开发语言·数据库·c++·sqlite
Evand J3 小时前
【MATLAB例程,PMSM19】永磁同步电机(PMSM)基于多速率无迹卡尔曼滤波(UKF)的转速与转子位置估计。测量缺失、状态预测与恢复性能分析
开发语言·matlab·电机·ekf·卡尔曼·电机滤波
喵了几个咪3 小时前
GoWind Flow 拆解:一个 Go 工作流引擎与它的双模式设计器
开发语言·人工智能·后端·golang
꧁细听勿语情꧂4 小时前
二叉树余题,排序、直接插入排序、希尔排序
c语言·开发语言·数据结构·算法
是main不是漫4 小时前
【C++——类和对象(上)】筑基篇:以封装奠定面向对象之基
c语言·开发语言·c++