C# sort 委托使用

本文介绍了一种使用C#进行泛型集合排序的方法,通过匿名方法委托Comparison<T>来实现对自定义类型Student的属性进行排序。示例中展示了如何根据年级和姓名对列表进行排序。
泛型的排序有3种方法,分别是:
1、List<T>.Sort(),只能在集合元素实现了IComparable泛型接口时使用
2、List<T>.Sort(Comparison<T>),Comparison<T>是一个方法委托,它带有2个参数T,返回int类型,可以灵活指定如何排序,但是需要编码时手动指定如何排序;
3、List<T>.Sort(IComparer<T>),使用实现了IComparer<T>接口的类给集合排序,可以灵活指定如何排序,但是需预先定义好类的排序方法

这里介绍第二种方法:
首先定义一个类,用作集合的元素
using System;
using System.Collections.Generic;


/// <summary>
/// 学生类
/// </summary>
public class Student
{
    private string name;
    // 姓名
    public string Name
    {
        get { return name; }
        set { }
    }
    private int age;
    // 年龄
    public int Age
    {
        get { return age; }
        set { age = value; }
    }

    private string grade;
    // 年级
    public string Grade
    {
        get { return grade; }
        set { grade = value; }
    }


    //构造函数
    public Student(string name, int age, string grade)
    {
        this.name = name;
        this.age = age;
        this.grade = grade;
    }
    public override string ToString()
    {
        return this.name + "," + this.age.ToString() + "," + this.grade;
    }
}


下面就开始排序了:
using System;
using System.Collections.Generic;
public class test
{
    public static void Main()
    {
        List<Student> arr = new List<Student>();
        arr.Add(new Student("张三", 7, "一年级"));
        arr.Add(new Student("李四", 11, "二年级"));
        arr.Add(new Student("王五", 21, "一年级"));
        arr.Add(new Student("陈六", 8, "三年级"));
        arr.Add(new Student("刘七", 15, "二年级"));
       
        // 调用Sort方法,传入一个匿名方法,实现按年级排序
        arr.Sort(delegate(Student x, Student y) { return x.Grade.CompareTo(y.Grade ); }); 

      
        // 循环显示集合里的元素
        foreach( Student item in arr)
            Console.WriteLine(item.ToString());


        // 调用Sort方法,传入一个匿名方法,实现按姓名排序
        arr.Sort(delegate(Student x, Student y) { return x.Name.CompareTo(y.Name); });   

    
        // 循环显示集合里的元素
        foreach( Student item in arr)
            Console.WriteLine(item.ToString());
    }
}


### 使用C#中的LINQ实现自定义排序 在C#中,`LINQ` 提供了强大的查询功能来操作集合数据。为了实现自定义排序,通常会使用 `OrderBy` 或 `ThenBy` 方法,并通过传递一个委托(通常是 lambda 表达式)来自定义比较逻辑。如果内置的比较器无法满足需求,则可以通过实现 `IComparer<T>` 接口创建自己的比较器。 下面是一个完整的例子,展示如何使用 LINQ 的 `OrderBy` 和 `ThenBy` 进行自定义排序: #### 自定义排序示例 假设有一个包含学生对象的列表,我们希望按照学生的年龄降序排列,然后再按姓名升序排列。 ```csharp using System; using System.Collections.Generic; using System.Linq; public class Student { public string Name { get; set; } public int Age { get; set; } public override string ToString() { return $"Name: {Name}, Age: {Age}"; } } class Program { static void Main(string[] args) { List<Student> students = new List<Student> { new Student { Name = "Alice", Age = 20 }, new Student { Name = "Bob", Age = 19 }, new Student { Name = "Charlie", Age = 20 }, new Student { Name = "David", Age = 21 } }; // 使用 OrderBy 和 ThenBy 实现自定义排序 var sortedStudents = students .OrderByDescending(student => student.Age) // 按照年龄降序排列 .ThenBy(student => student.Name); // 如果年龄相同则按名字升序排列 foreach (var student in sortedStudents) { Console.WriteLine(student); } } } ``` 在这个例子中,`OrderByDescending` 被用来指定主要的排序条件——即按年龄降序排列;而 `ThenBy` 则指定了次要的排序条件——当两个学生的年龄相同时,再根据他们的名字进行升序排列[^1]。 #### 创建并应用自定义比较器 对于更复杂的场景,可能需要实现 `IComparer<T>` 来提供完全定制化的比较行为。例如,如果我们想忽略大小写来进行字符串比较,可以这样做: ```csharp using System; using System.Collections.Generic; using System.Linq; public class CaseInsensitiveStringComparer : IComparer<string> { public int Compare(string x, string y) { if (x == null && y == null) return 0; if (x == null) return -1; if (y == null) return 1; return string.Compare(x.ToLower(), y.ToLower()); } } class Program { static void Main(string[] args) { List<string> names = new List<string> { "alice", "bob", "Charlie", "david" }; // 应用自定义比较器 var sortedNames = names.OrderBy(name => name, new CaseInsensitiveStringComparer()); foreach (var name in sortedNames) { Console.WriteLine(name); } } } ``` 在此代码片段中,实现了 `CaseInsensitiveStringComparer` 类作为 `string` 对象的一个不区分大小写的比较器,并将其应用于 `OrderBy` 中以确保排序时不考虑字母的大小写差异[^3]。 #### 动态查询库支持 除了标准的 LINQ 查询外,还可以利用动态查询库简化复杂表达式的构建过程。例如,借助于第三方工具包如 **System.Linq.Dynamic.Core** 可以编写更加灵活的查询语句[^2]: ```csharp using System; using System.Collections.Generic; using System.Linq; using System.Linq.Dynamic.Core; class Program { static void Main(string[] args) { List<Student> students = new List<Student> { new Student { Name = "Alice", Age = 20 }, new Student { Name = "Bob", Age = 19 }, new Student { Name = "Charlie", Age = 20 }, new Student { Name = "David", Age = 21 } }; // 动态查询语法 var result = students.AsQueryable().OrderBy("Age DESC, Name ASC").ToList(); foreach (var item in result) { Console.WriteLine(item.ToString()); } } } ``` 此方式允许开发者直接传入字符串形式的排序规则,从而减少硬编码带来的维护成本。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值