【从零开始入门unity游戏开发之——C#篇35】C#自定义类实现Sort自定义排序

文章目录

一、List自带的排序方法

1、List调用Sort()排序

List<T> 提供了一个内建的 Sort() 方法来对列表进行排序。它的基本用法如下:

csharp 复制代码
List<int> list = new List<int> { 3, 2, 6, 1, 4, 5 };
list.Sort(); // 默认升序排序

// 输出排序后的结果
foreach (int item in list)
{
    Console.WriteLine(item);
}

输出:

1
2
3
4
5
6

2、 能够使用 Sort() 方法进行排序的本质

List<int> 能够使用 Sort() 方法进行排序,背后的原因是 int string等类型实现了 IComparable<T> 接口

二、自定义类的排序

1、通过实现泛型IComparable<T> 接口

如果想对自定义对象排序,可以让自定义类实现 IComparable<T> 接口。在这个接口中,必须实现 CompareTo 方法来定义对象间的比较规则。

  • CompareTo 方法的基本结构

    csharp 复制代码
    public int CompareTo(T other)
    • T 是与当前对象进行比较的类型。
    • other 是传入的另一个对象,它与当前对象进行比较。
  • CompareTo 返回值的含义

    CompareTo 方法用于定义对象的排序规则。通过返回的整数值,来决定当前对象与传入对象之间的位置关系。

    • 返回 负值:当前对象排在传入对象前面。
    • 返回 0:当前对象与传入对象相等(不改变位置)。
    • 返回 正值:当前对象排在传入对象后面。

(1)示例

csharp 复制代码
public class Item : IComparable<Item>
{
    public int money;

    public Item(int money)
    {
        this.money = money;
    }

    public int CompareTo(Item? other)
    {
        if (other == null) return 1;

        if (this.money > other.money)
        {
            return 1;// 返回 `正值`:当前对象排在传入对象后面。
        }
        else if (this.money < other.money)
        {
            return -1;// 返回 `负值`:当前对象排在传入对象前面。
        }
        else
        {
            return 0;// 返回 `0`:当前对象与传入对象相等(不改变位置)。
        }
    }
}

调用.Sort()进行排序

csharp 复制代码
List<Item> itemList = new List<Item>
{
    new Item(45),
    new Item(10),
    new Item(99),
    new Item(24),
    new Item(100),
    new Item(12)
};

itemList.Sort(); // 使用 Sort() 排序

// 输出排序后的结果
foreach (Item item in itemList)
{
    Console.WriteLine(item.money);
}

输出:

10
12
24
45
99
100

如果想降序,CompareTo返回值正负反过来就行了

(2)直接调用 int 类型的 CompareTo 方法进行简化

这个做法更加简洁,也符合 CompareTo 方法的惯用方式,减少了手动判断大小的代码。

csharp 复制代码
public class Item : IComparable<Item>
{
    public int money;

    public Item(int money)
    {
        this.money = money;
    }

    public int CompareTo(Item? other)
    {
        if (other == null) return 1;

        // 按照 money 进行排序,升序
        return this.money.CompareTo(other.money);
    }
}

(3)降序排序

如果需要降序排序,只需要调整 CompareTo 方法中的返回值逻辑:

csharp 复制代码
public int CompareTo(Item other)
{
    if (other == null) return 1;
    
    // 降序排序
    return other.money.CompareTo(this.money);
}

2、 直接实现 IComparable 接口(不推荐)

如果你的类不使用泛型接口(IComparable<T>),你也可以使用非泛型的 IComparable 接口来实现排序:

csharp 复制代码
public class Item : IComparable
{
    public int Money { get; set; }

    public Item(int money)
    {
        Money = money;
    }

    // 实现 IComparable 接口的 CompareTo 方法
    public int CompareTo(object obj)
    {
        if (obj == null) return 1;

        Item other = obj as Item;
        if (other == null) throw new ArgumentException("Object is not an Item");

        return this.Money.CompareTo(other.Money);  // 默认升序排序
    }
}

这种方式的缺点是需要处理类型转换(as 或者显式转换),并且代码更加冗长。一般情况下,推荐使用泛型 IComparable<T>

3、通过委托函数进行自定义排序

可以通过传入自定义的比较方法(委托)来进行排序。此时,我们定义一个静态方法,并作为参数传入 到Sort() 方法进行排序。

返回值规则和之前一样 0做标准 负数在左(前) 正数在右(后)

(1)示例

csharp 复制代码
using System;

public class ShopItem
{
    public int id;

    public ShopItem(int id)
    {
        this.id = id;
    }
}

class Program
{
    static int SortShopItem(ShopItem a, ShopItem b)
    {
        return a.id.CompareTo(b.id);  // 升序
        // return b.id.CompareTo(a.id);  // 降序
    }

    static void Main()
    {
        List<ShopItem> shopItems = new List<ShopItem>
        {
            new ShopItem(2),
            new ShopItem(1),
            new ShopItem(4),
            new ShopItem(3),
            new ShopItem(6),
            new ShopItem(5)
        };

        shopItems.Sort(SortShopItem); // 使用委托排序

        // 输出排序后的结果
        foreach (ShopItem item in shopItems)
        {
            Console.WriteLine(item.id);
        }
    }
}

输出:

1
2
3
4
5
6

(2)使用匿名方法(Delegate)简化

我们也可以使用匿名方法(Delegate)进行排序。这种方法比较灵活,但代码可能会显得比较长:

csharp 复制代码
using System;

public class ShopItem
{
    public int id;

    public ShopItem(int id)
    {
        this.id = id;
    }
}

class Program
{
    static void Main()
    {
        List<ShopItem> shopItems = new List<ShopItem>
        {
            new ShopItem(2),
            new ShopItem(1),
            new ShopItem(4),
            new ShopItem(3),
            new ShopItem(6),
            new ShopItem(5)
        };

        shopItems.Sort(delegate (ShopItem a, ShopItem b){
            return a.id.CompareTo(b.id);  // 升序
            // return b.id.CompareTo(a.id);  // 降序
        });

        // 输出排序后的结果
        foreach (ShopItem item in shopItems)
        {
            Console.WriteLine(item.id);
        }
    }
}

(3)再使用 Lambda 表达式简化

Lambda 表达式可以让代码更加简洁。它是对委托的一种简化形式,常用于排序操作。

csharp 复制代码
shopItems.Sort((a, b) => {
    return a.id.CompareTo(b.id);  // 升序
    // return b.id.CompareTo(a.id);  // 降序
});

或者更简洁的形式

csharp 复制代码
shopItems.Sort((a, b) => a.id.CompareTo(b.id));  // 升序;
//shopItems.Sort((a, b) => b.id.CompareTo(a.id));  // 降序;

三、总结

  • List<T>.Sort() 方法可以直接排序常用类型(如 int, double, string 等)。
  • 对于自定义类型,推荐实现 IComparable<T> 接口,这样可以直接使用 Sort() 方法。
  • 如果不希望修改类本身,也可以通过传入委托函数、匿名方法或 Lambda 表达式来进行排序。
  • 对于需要降序排序的情况,可以调整 CompareTo 方法的返回值,或者在委托中修改比较逻辑。

专栏推荐

地址
【从零开始入门unity游戏开发之------C#篇】
【从零开始入门unity游戏开发之------unity篇】
【制作100个Unity游戏】
【推荐100个unity插件】
【实现100个unity特效】
【unity框架开发】

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信或者加群找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

相关推荐
ou.cs3 分钟前
c# 快捷键模块
c#
唐棣棣3 分钟前
期末速成C++【知识点汇总完】
开发语言·c++
yannan201903138 分钟前
【数据结构】(Python)差分数组。差分数组与树状数组结合
开发语言·python·算法
中國移动丶移不动10 分钟前
Java List 源码解析——从基础到深度剖析
java·后端·list
belldeep1 小时前
C#:多线程 简单示例
c#·多线程·thread
Java知识技术分享1 小时前
spring boot 异步线程池的使用
java·spring boot·spring
m0_748232921 小时前
Springboot3.x整合swagger3
java
东林知识库1 小时前
Mysql高级
java·mysql
m0_748248231 小时前
Springboot项目:使用MockMvc测试get和post接口(含单个和多个请求参数场景)
java·spring boot·后端
顾北辰201 小时前
基本算法——回归
java·spring boot·机器学习