20250606-C#知识:List排序

C#知识:List排序

默认排序往往不够用,学会自定义排序很重要。


1、默认排序

  • 只有少数类型能用,例如值类型int、float,double等
  • 默认升序
csharp 复制代码
//系统自带排序
List<int> list = new();
list.Add(5);
list.Add(8);
list.Add(1);
list.Add(6);
list.Add(2);
Print<int>(list);   //5 8 1 6 2
//系统默认排序方法,默认升序
list.Sort();
Print<int>(list);   //1 2 5 6 8

2、实现IComparable接口

  • 重写CompareTo方法,实现排序逻辑
csharp 复制代码
class Equipment:IComparable<Equipment>
{
    public string equipmentName;
    public int damage;
    public float price;

    public Equipment(string equipmentName, int damage, float price)
    {
        this.equipmentName = equipmentName;
        this.damage = damage;
        this.price = price;
    }

    public int CompareTo(Equipment? other)
    {
        if(this.price > other.price)
            return -1;
        else if(this.price < other.price)
            return 1;
        return 0;
    }

    public override string ToString()
    {
        return $" 【名称:{equipmentName}, 伤害:{damage}, 价格:{price}】";
    }
}
csharp 复制代码
List<Equipment> equipments = new List<Equipment>();
equipments.Add(new Equipment("猎犬长牙", 58, 100));
equipments.Add(new Equipment("碎星大剑", 120, 500));
equipments.Add(new Equipment("陨石杖", 60, 300));
equipments.Add(new Equipment("黄铜盾", 0, 200));
//以实现接口方式:价格降序排序
equipments.Sort();  //不实现接口直接排序会报错Unhandled exception. System.InvalidOperationException: Failed to compare two elements in the array.
Print<Equipment>(equipments);//【名称:碎星大剑, 伤害:120, 价格:500】  【名称:陨石杖, 伤害:60, 价格:300】  【名称:黄铜盾, 伤害:0, 价格:200】  【名称:猎犬长牙, 伤害:58, 价格:100】

3、传递委托函数

  • 直接Sort方法传入委托函数参数
csharp 复制代码
//Sort传入委托函数
//伤害升序
equipments.Sort((a, b) =>
{
    if (a.damage > b.damage)
        return 1;
    else if (a.damage < b.damage)
        return -1;
    return 0;
});
Print<Equipment>(equipments);//【名称:黄铜盾, 伤害:0, 价格:200】  【名称:猎犬长牙, 伤害:58, 价格:100】  【名称:陨石杖, 伤害:60, 价格:300】  【名称:碎星大剑, 伤害:120, 价格:500】

4、完整代码示例

csharp 复制代码
namespace LearnListSort
{
    class Equipment:IComparable<Equipment>
    {
        public string equipmentName;
        public int damage;
        public float price;

        public Equipment(string equipmentName, int damage, float price)
        {
            this.equipmentName = equipmentName;
            this.damage = damage;
            this.price = price;
        }

        public int CompareTo(Equipment? other)
        {
            if(this.price > other.price)
                return -1;
            else if(this.price < other.price)
                return 1;
            return 0;
        }

        public override string ToString()
        {
            return $" 【名称:{equipmentName}, 伤害:{damage}, 价格:{price}】";
        }
    }
    
    internal class Program
    {
        static void Print<T>(List<T> list)
        {
            foreach (T item in list)
            {
                Console.Write(item.ToString() + " ");
            }
            Console.WriteLine();
        }
        static void Main(string[] args)
        {
            //系统自带排序
            List<int> list = new();
            list.Add(5);
            list.Add(8);
            list.Add(1);
            list.Add(6);
            list.Add(2);
            Print<int>(list);   //5 8 1 6 2
            //系统默认排序方法,默认升序
            list.Sort();
            Print<int>(list);   //1 2 5 6 8

            List<Equipment> equipments = new List<Equipment>();
            equipments.Add(new Equipment("猎犬长牙", 58, 100));
            equipments.Add(new Equipment("碎星大剑", 120, 500));
            equipments.Add(new Equipment("陨石杖", 60, 300));
            equipments.Add(new Equipment("黄铜盾", 0, 200));
            //以实现接口方式:价格降序排序
            equipments.Sort();  //不实现接口直接排序会报错Unhandled exception. System.InvalidOperationException: Failed to compare two elements in the array.
            Print<Equipment>(equipments);//【名称:碎星大剑, 伤害:120, 价格:500】  【名称:陨石杖, 伤害:60, 价格:300】  【名称:黄铜盾, 伤害:0, 价格:200】  【名称:猎犬长牙, 伤害:58, 价格:100】
            //Sort传入委托函数
            //伤害升序
            equipments.Sort((a, b) =>
            {
                if (a.damage > b.damage)
                    return 1;
                else if (a.damage < b.damage)
                    return -1;
                return 0;
            });
            Print<Equipment>(equipments);//【名称:黄铜盾, 伤害:0, 价格:200】  【名称:猎犬长牙, 伤害:58, 价格:100】  【名称:陨石杖, 伤害:60, 价格:300】  【名称:碎星大剑, 伤害:120, 价格:500】
        }
    }
}

5、参考资料

  1. 《唐老狮C#》

本文结束,感谢您的阅读~

相关推荐
李建军5 小时前
界止签章宗地号替换工具
c#
qq_425263325 小时前
.net开发框架和语言
c#
武藤一雄5 小时前
C# 关于多线程如何实现需要注意的问题(持续更新)
windows·后端·microsoft·c#·.net·.netcore·死锁
flysh055 小时前
C# 架构设计:接口 vs 抽象类的深度选型指南
开发语言·c#
flysh056 小时前
C# 中类型转换与模式匹配核心概念
开发语言·c#
故事不长丨8 小时前
C#字典(Dictionary)全面解析:从基础用法到实战优化
开发语言·c#·wpf·哈希算法·字典·dictionary·键值对
wtsolutions10 小时前
Sheet-to-Doc占位符系统详解:让数据自动填入Word指定位置
开发语言·c#
kylezhao201911 小时前
C#上位机多语言切换实现
c#·工控上位机
我是唐青枫11 小时前
深入理解 System.Lazy<T>:C#.NET 延迟初始化与线程安全
c#·.net
zxy284722530111 小时前
利用C#对接BotSharp本地大模型AI Agent示例(2)
人工智能·c#·api·ai agent·botsharp