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

所属分类: 软件编程 / C#教程 阅读数: 76
收藏 0 赞 0 分享

前言

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

IComparable接口

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

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

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

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

示例:

  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)来进行我们的排序

执行测试

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);
      }
    }
  }

输出如下

IComparer接口

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

示例

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

执行测试

 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);
      }
    }
  }

输出结果如下

IComparable 和IComparer

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

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

IComparable

  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

  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

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

更多精彩内容其他人还在看

C#获取并修改文件扩展名的方法

这篇文章主要介绍了C#获取并修改文件扩展名的方法,实例分析了C#编程方式修改文件扩展名的技巧,涉及Path类的使用方法,需要的朋友可以参考下
收藏 0 赞 0 分享

C#遍历操作系统下所有驱动器的方法

这篇文章主要介绍了C#遍历操作系统下所有驱动器的方法,涉及C#中DriveInfo类GetDrivers方法的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C#遍历指定目录下所有文件的方法

这篇文章主要介绍了C#遍历指定目录下所有文件的方法,实例分析了C#中GetFiles()方法遍历文件的使用技巧,非常具有实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C#拷贝文件简单实现方法

这篇文章主要介绍了C#拷贝文件简单实现方法,主要分析了FileInfo类中CopyTo方法针对文件复制的操作技巧,非常简单实用,需要的朋友可以参考下
收藏 0 赞 0 分享

C#获取文件相关信息的方法

这篇文章主要介绍了C#获取文件相关信息的方法,涉及C#中FileInfo类的相关使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C#交错数组用法实例

这篇文章主要介绍了C#交错数组用法,较为详细的分析了交错数组的概念、用法并实例分析了交错数组的使用技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

C#实现在前端网页弹出警告对话框(alert)的方法

这篇文章主要介绍了C#实现在前端网页弹出警告对话框(alert)的方法,涉及C#通过自定义函数调用window.alert方法弹出对话框的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C#实现控制Windows系统关机、重启和注销的方法

这篇文章主要介绍了C#实现控制Windows系统关机、重启和注销的方法,涉及C#调用windows系统命令实现控制开机、关机等操作的技巧,非常简单实用,需要的朋友可以参考下
收藏 0 赞 0 分享

C#读取Excel并转化成XML的方法

这篇文章主要介绍了C#读取Excel并转化成XML的方法,实例分析了C#操作Excel及XML文件的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C#创建一个Word并打开的方法

这篇文章主要介绍了C#创建一个Word并打开的方法,实例分析了C#操作word的常用技巧,非常具有实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多