zoukankan      html  css  js  c++  java
  • C# 中的IComparable和IComparer

    前言

    在开发过程中经常会遇到比较排序的问题,比如说对集合数组的排序等情况,基本类型都提供了默认的比较算法,如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

    转 https://www.cnblogs.com/yyfh/p/12129000.html

  • 相关阅读:
    复习:C#3.0面向对象测试开发包
    SQL Server 2000实现一则按类似VB VAL函数功能排序的案例
    SQL Server TEXT类型字段字符串替换示例处理脚本
    获取SQL Server服务器的连接信息用脚本(在原邹建写的基础上作一点改进)与一段查询SQL Server服务器阻塞和死锁信息用的脚本
    字符串前部去除自定义函数(TSQL)
    从数据库系统管理的角度上回答数据库是什么
    话说物联网
    赖床狂想记录
    M1非接触式射频存储卡卡唯一号(十六进制值表示),去除其前部为0的自定义函数
    SQLHelper类
  • 原文地址:https://www.cnblogs.com/wl-blog/p/15478937.html
Copyright © 2011-2022 走看看