服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C# 中的IComparable和IComparer的使用及区别

C# 中的IComparable和IComparer的使用及区别

2022-08-16 09:43HueiFeng C#

这篇文章主要介绍了C# 中的IComparable和IComparer的使用及区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

在开发过程中经常会遇到比较排序的问题,比如说对集合数组的排序等情况,基本类型都提供了默认的比较算法,如string提供了按字母进行排序,而int整数则是根据整数大小进行排序.但是在引用类型中(具有多个字段),那么这个排序当然也是取决于我们特定的值。

IComparable接口

该接口由其值可以排序或排序的类型实现,并提供强类型的比较方法以对泛型集合对象的成员进行排序,例如数字可以大于第二个数字,一个字符串可以在另一个字符串之前以字母顺序出现。他要求实现类型定义的一个方法,CompareTo(T)该方法指示当前实现在排序顺序中的位置是在同一个类型和第二个对象之前、之后还是与其相同。通常,不会直接从开发人员代码中调用方法。相反他由List .Sort()和Add等方法自动调用。

通常,提供Icomparable 实现的类型还IEquatable 实现接口。IEquatable 接口Equals定义方法,该方法确定实现类型的实例的相等性。

CompareTo(T)方法的实现必须Int32返回具有以下三个值之一的,如下表所示。

 

含义
小于零 此对象在排序顺序中位于CompareTo方法所指定的对象之前。
此当前实例在排序顺序中与CompareTo方法参数指定的对象出现在同一位置。
大于零 此当前实例位于排序顺序中由CompareTo方法自变量指定的对象之后。

 

示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Student : IComparable
{
  public string Name { get; set; }
 
  public int Age { get; set; }
  public int CompareTo(object obj)
  {
    if (!(obj is Student))
    {
      throw new ArgumentException("Compared Object is not of student");
    }
    Student student = obj as Student;
    return Age.CompareTo(student.Age);
  }
}

Ps:我们根据通过Age(int)来进行我们的排序

执行测试

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Program
  {
    static void Main(string[] args)
    {
      ArrayList studentList = new ArrayList {
        new Student{Name="a",Age=9 },
         new Student{Name="a3",Age=7 },
         new Student{Name="a1",Age=6 },
         new Student{Name="a2",Age=10 },
      };
      studentList.Sort();
      StudentComparable(studentList);
 
      Console.ReadLine();
    }
 
    private static void StudentComparable(ArrayList studentList)
    {
      foreach (Student item in studentList)
      {
        Console.WriteLine("Name:{0},Age:{1}", item.Name, item.Age);
      }
    }
  }

输出如下

C# 中的IComparable和IComparer的使用及区别

IComparer接口

IComparable 接口的CompareTo方法一次只能对一个字段进行排序,因此无法对不同的属性进行排序。IComparer接口提供了Compare方法,该方法比较两个对象并返回一个值,该值指示一个对象小于,等于或大于另一个对象。实现IComparer接口的类必须提供比较两个对象的Compare方法。例如,您可以创建一个StudentComparer类,该类实现IComparer,并具有一个Compare方法,该方法按Name比较Student对象。然后,您可以将StudentComparer对象传递给Array.Sort方法,它可以使用该对象对Student对象的数组进行排序。

示例

?
1
2
3
4
5
6
7
8
9
10
class StudentComparer : IComparer
{
 
  public int Compare(object x, object y)
  {
    Student x1 = x as Student;
    Student y1 = y as Student;
    return x1.Name.CompareTo(y1.Name);
  }
}

Ps:我们根据Name(string)进行排序

执行测试

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Program
 {
   static void Main(string[] args)
   {
     ArrayList studentList = new ArrayList {
       new Student{Name="a",Age=9 },
        new Student{Name="a3",Age=7 },
        new Student{Name="a1",Age=6 },
        new Student{Name="a2",Age=10 },
     };
     studentList.Sort(new StudentComparer());
     StudentComparable(studentList);
 
     Console.ReadLine();
   }
 
   private static void StudentComparable(ArrayList studentList)
   {
     foreach (Student item in studentList)
     {
       Console.WriteLine("Name:{0},Age:{1}", item.Name, item.Age);
     }
   }
 }

输出结果如下

C# 中的IComparable和IComparer的使用及区别

IComparable 和IComparer

上述示例中我们将对象进行了多次的装箱和拆箱,那么此时我们可以将方法改为泛型的,泛型的出现也让我们避免了装箱和拆箱的资源浪费.

最终我们实现的代码片段如下:

IComparable

?
1
2
3
4
5
6
7
8
9
10
11
class Student : IComparable<Student>
{
  public string Name { get; set; }
 
  public int Age { get; set; }
 
  public int CompareTo([AllowNull] Student other)
  {
    return Age.CompareTo(other.Age);
  }
}

IComparer

?
1
2
3
4
5
6
7
8
9
class StudentComparer : IComparer<Student>
{
 
  public int Compare([AllowNull] Student x, [AllowNull] Student y)
  {
    return x.Name.CompareTo(y.Name);
    
  }
}

总结

参考: https://docs.microsoft.com/en-us/dotnet/api/system.icomparable-1?view=netframework-4.8

示例: https://github.com/hueifeng/BlogSample/tree/master/src/CompareDemo

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://www.cnblogs.com/yyfh/p/12129000.html

延伸 · 阅读

精彩推荐
  • C#C#使用ICSharpCode.SharpZipLib.dll进行文件的压缩与解压功能

    C#使用ICSharpCode.SharpZipLib.dll进行文件的压缩与解压功能

    这篇文章主要介绍了C#使用ICSharpCode.SharpZipLib.dll进行文件的压缩与解压功能,需要的朋友可以参考下...

    华临天下7222022-02-17
  • C#C#位运算以及实例计算详解

    C#位运算以及实例计算详解

    这篇文章主要给大家介绍了关于C#位运算以及实例计算的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需...

    艾三元11432022-07-28
  • C#C#.net编程创建Access文件和Excel文件的方法详解

    C#.net编程创建Access文件和Excel文件的方法详解

    这篇文章主要介绍了C#.net编程创建Access文件和Excel文件的方法,结合实例形式总结分析了C#创建Access与Excel文件的几种常用技巧,具有一定参考借鉴价值,需要的...

    郑文亮3572021-11-25
  • C#WPF弹出自定义窗口的方法

    WPF弹出自定义窗口的方法

    这篇文章主要介绍了WPF弹出自定义窗口的方法,结合实例形式分析了WPF自定义窗口的创建与调用技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    kagula3972021-11-30
  • C#理解C#中参数的值和引用以及传递结构和类引用的区别

    理解C#中参数的值和引用以及传递结构和类引用的区别

    这篇文章主要介绍了理解C#中参数的值和引用以及传递结构和类引用的区别,文中举了两段代码例子来简单说明,需要的朋友可以参考下...

    C#教程网4872021-11-09
  • C#C#在图片增加文字的实现代码

    C#在图片增加文字的实现代码

    最近做项目需要动态给图片增加文字(书本的封面图片),修改字体大小、字体、颜色、控制位置等,下面通过实例代码给大家分享C#在图片增加文字的实...

    空空隆隆4432022-01-10
  • C#C# Email发送邮件 对方打开邮件可获得提醒

    C# Email发送邮件 对方打开邮件可获得提醒

    这篇文章主要为大家详细介绍了C# Email发送邮件功能,对方打开通知你,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    未知的路上4132022-02-10
  • C#C#抓取网络图片保存到本地的实现方法

    C#抓取网络图片保存到本地的实现方法

    下面小编就为大家分享一篇C#抓取网络图片保存到本地的实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    叶长种5722022-02-17