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#》

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

相关推荐
WYH2875 小时前
C#控制台输入(Read()、ReadKey()和ReadLine())
开发语言·c#
hqwest6 小时前
C#WPF实战出真汁06--【系统设置】--餐桌类型设置
c#·.net·wpf·布局·分页·命令·viewmodel
做一位快乐的码农9 小时前
基于.net、C#、asp.net、vs的保护大自然网站的设计与实现
c#·asp.net·.net
DavieLau9 小时前
C#项目WCF接口暴露调用及SOAP接口请求测试(Python版)
xml·服务器·开发语言·python·c#
张人玉10 小时前
C#Encoding
开发语言·c#
Hard but lovely10 小时前
C++:stl-> list的模拟实现
开发语言·c++·stl·list
hqwest12 小时前
C#WPF实战出真汁05--左侧导航
开发语言·c#·wpf·主界面·窗体设计·视图viewmodel
小码编匠14 小时前
C# Bitmap 类在工控实时图像处理中的高效应用与避坑
后端·c#·.net
qiuyunoqy14 小时前
list模拟实现
数据结构·c++·list
Kyln.Wu17 小时前
【python实用小脚本-187】Python一键批量改PDF文字:拖进来秒出新文件——再也不用Acrobat来回导
python·pdf·c#