C#排序比较

与C#定义了相等性比较规范一样,C#也定义了排序比较规范,以确定一个对象与另一个对象的先后顺序。排序规范如下

  • IComparable接口(包括IComparable接口和IComparable<T>接口)
  • >和<运算符

当需要实现排序算法时,使用IComparable接口。在下面的例子中,Array.Sort静态方法可以调用,是因为System.String类实现了IComparable接口。

string[] colors={"Green", "Red", "Blue"};
Array.Sort(colors)
foreach(string c in colors)
    Console.Write(c+ " ");

而<和>运算符比较特殊,因为他们一般用于比较数字类型。因为大于和小于运算符会被静态地解析,因此它们“产生”出高效的代码,适用于复杂计算的场景。

.NET Framework还提供了插件式的排序协议--IComparer接口。IComparable接口与IComparer接口的差别类似与IEquatable和IEqualityComparer接口 (关于IEqutable接口和IEqualityComparer接口,请参考C#相等性:http://www.cnblogs.com/yang_sy/p/3582946.html)

 

1. IComparable接口

IComparable接口的定义如下

public interface IComparable

    int CompareTo(Object obj);
}

public interface IComparable<in T>
{
    int CompareTo(T other);
}

这两个接口定义了相同的功能。对于值类型,IComparable<T>接口效率高于ICompare接口。上面的两个接口的CompareTo方法都按照下面的方式运行:

  • 如果a排在b后面,那么a.CompareTo(b)返回1
  • 如果a和不一样,那么返回0
  • 如果a排在不前面,那么返回-1

我们来看下面的示例代码:

IList<Staff> staffs = new List<Staff> 
{
    new Staff{FirstName="AAA", Title="Manager", Dept="Sale"},  
    new Staff{FirstName="BBB", Title="Accountant", Dept="Finance"},
    new Staff{FirstName="CCC", Title="Accountant", Dept="Finance"},
};

Console.WriteLine("BBB".CompareTo(staffs[0].FirstName)); // 1
Console.WriteLine("BBB".CompareTo(staffs[1].FirstName)); // 0
Console.WriteLine("BBB".CompareTo(staffs[2].FirstName)); // -1

C#的大部分基本类型都实现了IComparable接口和IComparable<T>接口。很多自定义类型同样也实现了该接口,这样便于排序。

IComarable与Equals

假设一个类型重写了Equals方法并实现了IComparable接口。那么你肯定希望当Equals返回true时,CompareTo应当返回0。而Equals返回false时,CompareTo可以返回任何值。

换句话说,相等性比对比性更严格;反之则不会。因此,当CompareTo说“两个对象相等”时,Equals会说“这两个对象不一定相等”。一个很好的例子来自System.String类。String.Equals方法和==运算符使用序号排序规则比较字符串--也就是通过每个字符的Unicode的值进行排序。而String.CompareTo方法,却使用不那么严格的基于文化区域(culture-dependent)进行比较。对于大多数计算机,字符ǖ和ṻ,Equals返回False,而CompareTo返回0

你可以实现通过IComparer接口,从而完成特定的排序算法。自定义IComparer接口的实现,进一步加大了CompareTo和Equals方法之间的差异。比如不区分大小写的字符串比较器,对于A和a,将返回0. 这也从反面印证了,ComparTo方法不如Equals方法严格。

 

2. <和>运算符

一些类型,定义了<和>运算符,比如:

bool after2010 = DateTime.Now > new DateTime(2010, 1, 1);
Console.WriteLine(after2010);

当实现<和>运算符之后,你需要保证<和>运算符与IComparable接口保持一致。这也是.NET Framework的标准。

同样地,当一个类型重载了<和>运算符,那么也要求实现IComparable接口,而反之则不需要。实际上,大多数.NET类型实现了IComparable接口,并没有重载<和>运算符。这(排序比较)与相等性比较不一样:

  • 在实现相等性比较时,如果重载了Equals方法,那么一般都重载==运算符
  • 而在实现排序性比较时,如果实现了CompareTo方法,一般不要求重载<运算符和>运算符

一般地,只有在下面的情形中,才需要重载<运算符和>运算符:

  • 一个类型本身包含大于和小于这样的概念
  • 执行先后顺序比较的方式是唯一的
  • 结果不会随文化区域(Cultures)变化而变化

System.Stirng类型不满足最后一条,因此string不支持>操作和<操作。因此 “beck” > “Anne”,编译时会抛出错误。

 

3. 实现IComparable接口

下面的实例代码中,结构Note表示一个音乐的注释,它实现了IComparable接口,还重载了<运算符和>运算符。为了实例的完整性,我们还重写了Equals和GetHashCode方法,以及重载了==和!=运算符,通过这个例子,你可以全面的了解排序比较。

internal struct Note : IComparable, IComparable<Note>, IEquatable<Note>
{

    private int semitonesFromA;
    public int SemitonesFromA
    {
        get { return semitonesFromA; }
    }

    public Note(int semitonesFromA)
    {
        this.semitonesFromA = semitonesFromA;
    }

    // generic IComparable<T>
    public int CompareTo(Note other)
    {
        if (Equals(other))
            return 0;
        return SemitonesFromA.CompareTo(other.SemitonesFromA);
    }

    // non-generic IComaparable
    public int IComparable.CompareTo(object other)
    {
        if (!(other is Note))
            throw new InvalidOperationException("CompareTo: Not a note");
        return CompareTo((Note)other);
    }

    public static bool operator <(Note n1, Note n2)
    {
        return n1.CompareTo(n2) < 0;
    }

    public static bool operator >(Note n1, Note n2)
    {
        return n1.CompareTo(n2) > 0;
    }

    // for IEquatable
    public bool Equals(Note other)
    {
        return this.SemitonesFromA == other.SemitonesFromA;
    }

    // override Object.Equals
    public override bool Equals(object other)
    {
        if (!(other is Note))
            throw new InvalidOperationException("CompareTo: Not a note");
        return Equals((Note)other);
    }

    public override int GetHashCode()
    {
        return SemitonesFromA.GetHashCode();
    }

    public static bool operator ==(Note n1, Note n2)
    {
        return n1.Equals(n2);
    }

    public static bool operator !=(Note n1, Note n2)
    {
        return !(n1 == n2);
    }
}

转载于:https://www.cnblogs.com/yang_sy/p/3593507.html

C#比较器对决:一文详解,如何用2大接口玩转对象排序魔法 通过这场比武大会,你不仅学会了如何在C#中使用和IComparer接口来实现对象的排序,更体会到了比较器在复杂对象世界中的重要性。就像魔法一样,比较器让对象世界井然有序,而你,正是那位掌握这门艺术的魔法师。继续你的探索,还有更多的魔法等待着你去发现! 阅读详情

相关推荐

Spring Boot 3.5.4 + LangChain4j实战:用Milvus搭建企业级RAG问答系统(附阿里百炼API配置)

本文详细介绍了如何利用Spring Boot 3.5.4、LangChain4j与Milvus构建企业级RAG问答系统。内容涵盖从架构设计、阿里百炼API安全配置、Milvus部署优化,到RAG检索、会话管理等核心实现,并提供了生产级API设计、监控集成及性能优化等实战经验,旨在帮助开发者打造高可用、可维护的Java AI应用。

weixin_29054399的博客 610

C#排序之不同排序的比较

1. 选择排序(Selection Sort): 2. 冒泡排序(Bubble Sort): 3. 插入排序(Insertion Sort): 4. 希尔排序(Shell Sort): 5. 归并排序(Merge Sort): 6. 快速排序(Quick Sort): 7. 堆排序(Heap Sort):

乌托托的博客 682

Ascend C 算子开发遇到的问题及解决方法

在学习Ascend C算子开发进阶课程的时候,进行Ascend C自定义算子工程、算子调用等实验,在开发环境中遇到了一些问题,在这里记录一下。首先如果在启智社区CANN版本为6.3 ,要进行Ascend C算子开发,需要更新CANN版本。

qq_45257495的博客 5109

C# 排序的多种实现方式

C# 排序的多种实现方式

weixin_42045136的博客 2961

手动安装SeuratData包中pbmc3k数据集的详细步骤与避坑指南

本文提供了手动安装SeuratData包中pbmc3k数据集的详细步骤与避坑指南。针对国内用户网络不稳定导致自动下载失败的问题,文章核心介绍了如何从错误信息中获取下载链接,使用浏览器或下载工具完成手动下载,并通过指定本地文件路径和参数在R中成功安装。该方法同样适用于SeuratData包中的其他数据集,是单细胞分析入门的必备生存技能。

weixin_29054399的博客 184

经典算法之——解决全排列问题以及详解

回溯”指的是“状态重置”,可以理解为“恢复现场”,是在编码的过程中,是为了节约空间而使用的,而在递归或者深度优先中根据需要的场合来配合回溯法可以进一步对自己的代码进行优化。, n-1, n},方向都为向左。邻位对换法是全排列生成算法中的其中一种,它的换位是双向的,通过保存数字的“方向性”来快速得到下一个排列。最后以 3 开头的全排列为[3, 1, 2], [3, 2, 1];以 1 开头的全排列为[1, 2, 3], [1, 3, 2];以 2 开头的全排列为[2, 1, 3], [2, 3, 1];

m0_68987535的博客 8795

【算法】C#实现经典排序算法总结(附动图)

自行整理的C#常见算法笔记。

好学若饥,谦卑若愚。 5248

Excel中如何快速地将成绩按比例来划分为等级?

问题介绍: 记录说明:班级里共有40个人,按最终总平均成绩从高到低划分等级,A等级30%,B等级50%,C等级20%。 部分成绩如下表所示: Excel中相关函数介绍: IF函数 IF函数有三个参数,语法如下: =IF(条件判断, 结果为真返回值, 结果为假返回值) 第一参数是条件判断,比如说“A1=">37”这种,判断TRUE或FALSE。如果判断是TRUE(结果为真)那么IF函数返回值是第二参数,否则(结果为假)返回第三参数。 如果省略了第三参数,则当结果为假时,会返回FALSE。 如果公式

Wendy的博客 1万+

C# 排序的多种实现方式(经典)

排序是我们编程时的常用操作,实现方式也有很多种,本篇文章列举几种我常用的用法,希望对大家有用!

寒冰屋的专栏 4386

【华为OD机试真题 2025C卷】895、贪心歌手 | 机试真题+思路参考+代码解析 (C++、Java、Py、C语言、JS)

【华为OD机试真题 2025C卷】895、贪心歌手 | 机试真题+思路参考+代码解析 (C++、Java、Py、C语言、JS) 华为od机试,华为od机试真题,华为od机试E卷,华为odE卷,华为od机试真题E卷,华为OD,华为OD机试,华为OD机试真题,华为od机考,华为od机试D卷,华为od机试真题D卷,华为od手撕代码,华为od,华为od机试C卷,华为od e卷,华为2025e卷,od机试,2025E卷,华为OD机试E卷,什么是华为od,华为od介绍,全面了解华为od,2025华为od,如何备战华

KJ.JK 964

第18章:Ingestion Pipeline 数据摄取流水线

本文介绍了LlamaIndex的IngestionPipeline如何解决合同文档处理中的四大核心问题:不可重复、无追溯、无容错和无法缓存。通过标准化数据处理流程,将手工操作升级为工厂流水线模式,实现数据的可复用、可追踪和高效处理。文章详细阐述了Pipeline的设计原理,包括Transformation的串行编排、缓存机制(基于输入和Transformation的哈希值)以及数据血缘追踪(通过Node的metadata记录处理过程)。

davidwang456的专栏 62

C# 排序比较

在C# 的进化过程中不断简化了对象的比较方式 Type1: public void compare2() { Product pct = new Product(); List pcts = pct.Products(); //直接上委托 pcts.Sort(delegate(Pr

炘的专栏 1207

WIN10系统下VS2019编译CloudCompare2.12.4

CloudCompare2.12.4

点云侠的博客 3143

C#基础之数组排序,对象大小比较

转载自:http://www.cnblogs.com/yukaizhao/archive/2011/08/19/csharp-compare.html 从个小例子开始: ? 1 2 3 int[] intArray = new int[]{2,3,6,1,4,5}; Array.Sort(intArray);

AchillesJPS的专栏 1871

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

C#排序函数和自定义比较器

C#排序函数和自定义比较器 例子

kydkong的博客 6315

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C#中,如何使用自定义比较器对List进行排序?

这两种方法(自定义比较器类和 lambda 表达式/匿名方法)都可以灵活地定义排序逻辑,以满足特定的需求。自定义比较器允许定义排序的具体规则,而不仅仅是依赖元素的默认比较方式。如果不需要创建一个单独的比较器类,也可以使用 lambda 表达式或匿名方法作为。方法,该方法接受两个参数并返回一个整数,表示它们在排序序列中的相对位置。以下是一个简单的步骤指南,说明如何使用自定义比较器对。在C#中,可以使用自定义比较器(方法,并传入自定义比较器实例。类用于对整数进行降序排序。中定义的规则进行排序。

学习和分享 690

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

C#比较接口和排序

class Program { static void Main(string[] args) { TestClass t1 = new TestClass(); t1.Score = 90; t1.Name = "lucy"; TestClass t2 = ne

u011878387的专栏 903

C#非比较排序(计数排序+基数排序)

非比较排序(计数排序+基数排序)C#

weixin_51565051的博客 150

C#中的比较和排序

当我们将一些数据存储在一个集合中时,往往会有排序的需求,比如游戏中的积分排行榜,学生考试系统中的分数排行,或者根据不同的条件(根据姓名、根据年龄)进行排序。当出现这些需求的时候,我们希望建立一种规则,根据这种规则就可以确定两个数据的前后关系。其实,这种规则我们就可以用接口来定义。 一、使用集合ArrayList排序 在列表中添加一些数据,打印列表的元素,得到如图 public class s1: MonoBehaviour { void Start () { List<int> lis

极客园地 2075

C# List 排序各种用法与比较

让数字字符串排序string[] strs = { "1", "111", "11", "999", "77" };             List&lt;string&gt; list = strs.ToList();             list.Sort(delegate (string s1, string s2) { return int.Parse(s1).CompareTo

Nemo的笔记本 6820

C# 对排序的认识( Comparison ) ,使用匿名方法实现比较器

  在C#中对数组及集合的排序(Sort) .需要提拱一个"比较器" (一个实现 IComparer 接口的类) 也可以用一个方法做比较器 这个方法 需要返回 0 1 或 -1. View Code 1 using System; 2 3 class ListSort 4 { 5 static void Main() 6 { 7 int[] nu...

weixin_30444105的博客 1237

【C#高性能排序技术内幕】:掌握并行排序与自定义比较器的黄金法则

掌握C#数据处理排序的高效实现方法,深入解析并行排序与自定义比较器的应用场景及性能优势,提升大数据量下的排序效率。适用于集合排序、复杂对象比较等实际需求,代码简洁可控,值得收藏。

SimProceed的博客 494

C# List.Sort()自定义比较方法排序

要用下面的routeName进行排序 类 public class BusRoute { private string routeName; private int stationCount; } 自定义比较方法 public static int Compare(BusRoute r1, BusRoute r2) { return r1.

云淡风轻的博客 9593

c#比较器 排序

原地址:http://blog.youkuaiyun.com/xutao_ustc/article/details/6314057 class Program { static void Main(string[] args) { Data[] array = new Data[] { new Data() { a = 1...

weixin_30323631的博客 114
上一篇: C#集合-列举(Enumeration)
下一篇: C#集合--数组
aoding8407
博客等级 码龄11年 2粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值