【C#】自定义List排序规则的两种方式

目录

1.系统排序原理

2.方式一:调用接口并重写

3.方式二:传排序规则函数做参数


1.系统排序原理

当我们对一个List<int>类型的数组如list1排序时,一个轻松的list1.sort();帮我们解决了问题

但是在实际应用过程中,往往我们遇到的问题会更加棘手

比如这样一个类:

cs 复制代码
    class BagItem
    {
        public int id;
        public string name;
        public int count;
        public BagItem(int id, string name, int count)
        {
            this.id = id;
            this.name = name;
            this.count = count;
        }
    }

这是一个背包物品类,包含了物品编号id,物品名称name,物品数量count

cs 复制代码
            List<BagItem> bagItems = new List<BagItem>();
            //传入参数依次为id,name,count
            bagItems.Add(new BagItem(1, "生命药水", 5));
            bagItems.Add(new BagItem(2, "魔力药水", 12));
            bagItems.Add(new BagItem(3, "速度药水", 7));
            bagItems.Add(new BagItem(4, "铁皮药水", 3));
            bagItems.Add(new BagItem(5, "重力药水", 9));
            bagItems.Add(new BagItem(6, "回城药水", 2));
            bagItems.Sort();

当我们创建一个List<BagItem>数组并想对它排序时,猜猜会发生什么?

这时系统会报错

想要弄明白为什么报错,需要先解释一个sort排序的原理

sort排序时会用到CompareTo函数, 这个函数方法存放在IComparable接口

之前我们List<int>类型数组排序能够成功是因为int类调用了上述接口并实现,所以sort排序时可以成功运行
可以看到int类调用了IComparable接口

而我们自己写的类调用不到对应类型的函数,所以运行失败

接下来将介绍两种方法时得我们自己写的类可以成功排序

2.方式一:调用接口并重写

既然int类可以调用,我们也可以给自己写的类调用这个接口

cs 复制代码
    class BagItem:IComparable<BagItem>
    {
        public int id;
        public string name;
        public int count;
        public BagItem(int id, string name, int count)
        {
            this.id = id;
            this.name = name;
            this.count = count;
        }

        public int CompareTo(BagItem other)
        {
            //返回类型int
            //返回值>0时,当前成员排在other成员右边
            //返回值<0时,当前成员排在other成员左边
            //可以理解为other成员处于0位置
            if (other.count > this.count || (other.count == this.count && other.id >= this.id))
                return -1;
            else
                return 1;
        }
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            List<BagItem> bagItems = new List<BagItem>();
            //传入参数依次为id,name,count
            bagItems.Add(new BagItem(3, "生命药水", 5));
            bagItems.Add(new BagItem(2, "魔力药水", 12));
            bagItems.Add(new BagItem(1, "速度药水", 12));
            bagItems.Add(new BagItem(5, "铁皮药水", 3));
            bagItems.Add(new BagItem(4, "重力药水", 9));
            bagItems.Add(new BagItem(6, "回城药水", 2));
            foreach (BagItem item in bagItems)
            {
                Console.WriteLine("物品:{0},id:{1},数量{2}",item.name,item.id,item.count);
            }
            bagItems.Sort();
            Console.WriteLine("---------------------");
            foreach (BagItem item in bagItems)
            {
                Console.WriteLine("物品:{0},id:{1},数量{2}", item.name, item.id, item.count);
            }
        }
    }

3.方式二:传排序规则函数做参数

当我们查看sort用法时,我们可以看到它还有其他重载类型

我们默认使用的是第三种无参数的类型,如果我们写一个函数作为参数传入时,那么就可以使用第一类型,传入我们自己的比较规则。

cs 复制代码
    internal class Program
    {
        static void Main(string[] args)
        {
            List<BagItem> bagItems = new List<BagItem>();
            //传入参数依次为id,name,count
            bagItems.Add(new BagItem(3, "生命药水", 5));
            bagItems.Add(new BagItem(2, "魔力药水", 12));
            bagItems.Add(new BagItem(1, "速度药水", 12));
            bagItems.Add(new BagItem(5, "铁皮药水", 3));
            bagItems.Add(new BagItem(4, "重力药水", 9));
            bagItems.Add(new BagItem(6, "回城药水", 2));
            foreach (BagItem item in bagItems)
            {
                Console.WriteLine("物品:{0},id:{1},数量{2}",item.name,item.id,item.count);
            }
            bagItems.Sort(SortBagItems);
            Console.WriteLine("---------------------");
            foreach (BagItem item in bagItems)
            {
                Console.WriteLine("物品:{0},id:{1},数量{2}", item.name, item.id, item.count);
            }
        }
        static int SortBagItems(BagItem left,BagItem right)
        {
            //返回类型int
            //返回值>0时,当前成员排在other成员右边
            //返回值<0时,当前成员排在other成员左边
            //可以理解为other成员处于0位置
            if (right.count > left.count || (right.count == left.count && right.id >= left.id))
                return -1;
            else
                return 1;
        }
    }
相关推荐
灯澜忆梦3 小时前
GO_并发编程---定时器
开发语言·后端·golang
-银雾鸢尾-3 小时前
C#中的StringBuilder相关方法
开发语言·c#
-银雾鸢尾-3 小时前
C#中结构体与类的区别;抽象类与接口的区别
开发语言·c#
大模型码小白4 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
段一凡-华北理工大学6 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
Ljwuhe6 小时前
C++——多态
开发语言·c++
心平气和量大福大7 小时前
C#-WPF-Window主窗体
开发语言·c#·wpf
白露与泡影8 小时前
Arthas 实战指南:从方法耗时定位到 JVM 变量热修改
服务器·jvm·c#
从零开始的代码生活_9 小时前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法
云小逸9 小时前
【C++ 第七阶段:模板、泛型编程与工程综合详解】
开发语言·c++