当前位置: 首页 > article >正文

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

文章目录

  • 一、List<T>自带的排序方法
    • 1、List<T>调用Sort()排序
    • 2、 能够使用 `Sort()` 方法进行排序的本质
  • 二、自定义类的排序
    • 1、通过实现泛型`IComparable<T>` 接口
      • (1)示例
      • (2)直接调用 int 类型的 CompareTo 方法进行简化
      • (3)降序排序
    • 2、 直接实现 IComparable 接口(不推荐)
    • 3、通过委托函数进行自定义排序
      • (1)示例
      • (2)使用匿名方法(`Delegate`)简化
      • (3)再使用 Lambda 表达式简化
  • 三、总结
  • 专栏推荐
  • 完结

一、List自带的排序方法

1、List调用Sort()排序

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

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 方法的基本结构

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

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

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

(1)示例

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()进行排序

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 方法的惯用方式,减少了手动判断大小的代码。

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 方法中的返回值逻辑:

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

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

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

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)示例

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)进行排序。这种方法比较灵活,但代码可能会显得比较长:

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 表达式可以让代码更加简洁。它是对委托的一种简化形式,常用于排序操作。

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

或者更简洁的形式

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

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


http://www.kler.cn/a/463687.html

相关文章:

  • 我的桌面 1.9.75 | 个性化定制手机桌面,丰富的小组件和主题
  • 计算机网络•自顶向下方法:网络层介绍、路由器的组成
  • PostgreSQL对称between比较运算
  • 华为ensp-BGP路由过滤
  • HackMyVM-Airbind靶机的测试报告
  • 【AUTOSAR 基础软件】Can模块详解(Can栈之驱动模块)
  • net core程序部署到 iis 出现跨域问题
  • Spring Boot JPA Oracle 最佳实践 20 条
  • 《迁移学习与联邦学习:推动人工智能发展的关键力量》
  • APP怎么抓取原生日志 - Android篇
  • springboot3.X 无法解析parameter参数问题
  • vue.js scoped样式冲突
  • 【mediapipe】实现卷腹运动识别(视频或摄像头)并计数
  • html 音频和视频组件
  • Kubernetes Gateway API-3-TLS配置
  • CES Asia 2025:助力新型城市基础设施建设,展现智慧城市科技魅力
  • Modbus知识详解
  • 单片机--51- RAM
  • @colyseus/loadtest 插件详解
  • 代码随想录算法训练营第十七天-二叉树-654.最大二叉树
  • STM32-笔记19-串口打印功能
  • arm rk3588 升级glibc2.31到2.33
  • AIGC与未来的通用人工智能(AGI):从生成内容到智能革命
  • 华为云Welink数据怎么连接到小满CRM?
  • gesp(C++一级)(12)洛谷:B3953:[GESP202403 一级] 找因数
  • 电脑与手机