【学习笔记】c#中的IComparable和IComparer

原文地址:https://www.cnblogs.com/pizzabig/p/5341088.html

仅仅为了自己查看方便。

在c#中自定义类型实现比较和排序需要自定义类实现IComparable接口,需要实现一个名为CompareTo的方法,返回值为int唯一参数为object。

1.创建一个员工类包含Id Name Salary三个属性 继承自IComparable接口并实现CompareTo方法

 1 using System;
 2 using System.Collections;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace IComparableTest2 {
 9     class Program {
10         static void Main(string[] args) {
11             var myList = new ArrayList();
12             myList.Add(new Employee(002, "Sam", 3000));
13             myList.Add(new Employee(001, "Mary", 2800));
14             myList.Add(new Employee(003, "Jick", 3800));
15             myList.Add(new Employee(004, "July", 3200));
16             myList.Sort();
17             foreach (var e in myList)
18             {
19                 Console.WriteLine(e.ToString());
20             }
21             Console.ReadKey();
22         }
23     }
24 
25     class Employee : IComparable {
26         public int Id { get; set; }
27         public string Name { get; set; }
28         public int Salary { get; set; }
29 
30         public Employee(int id, string name, int salary) {
31             this.Id = id;
32             this.Name = name;
33             this.Salary = salary;
34         }
35 
36         public override string ToString() {
37             return "ID:" + Id + "  Name:" + Name + "  Salary:" + Salary;
38         }
39 
40         public int CompareTo(object o) {
41             Employee others = (Employee)o;
42             if (this.Id > others.Id)
43             {
44                 return 1;
45             }
46             else if (this.Id < others.Id)
47             {
48                 return -1;
49             }
50             else
51             {
52                 return 0;
53             }
54         }
55     }
56 }

上面的CompareTo方法对Id作比较,Employee将会以Id作为键做比较,排序时键值为Id做升序。

输出结果:

ID:1 Name:Mary Salary:2800
ID:2 Name:Sam Salary:3000
ID:3 Name:Jick Salary:3800
ID:4 Name:July Salary:3200

其实int和string等预定义类型默认实现IComparable,Id的类型是int,所以可以直接进行比较。

将上面代码中CompareTo方法改为

1  public int CompareTo(object o) {
2             Employee others = (Employee)o;
3             return this.Id.CompareTo(others.Id);
4         }

效果相同。

2.如果希望以更灵活的方式进行比较,比如以工资作为键值进行排序,就需要声明一个继承自IComparer接口的比较器。

需要实现Comprae方法,返回值为int参数为2个object作为比较对象。

示例:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IComparerTest1;

namespace IComparerTest1 {
    class Program {
        static void Main(string[] args) {
            var myList = new ArrayList();
            myList.Add(new Employee(002, "Sam", 3000));
            myList.Add(new Employee(001, "Mary", 2800));
            myList.Add(new Employee(003, "Jick", 3800));
            myList.Add(new Employee(004, "July", 3200));
            myList.Sort(new SortBySalary());
            foreach (var e in myList)
            {
                Console.WriteLine(e.ToString());
            }
            Console.ReadKey();
        }
    }

    class Employee {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Salary { get; set; }

        public Employee(int id, string name, int salary) {
            this.Id = id;
            this.Name = name;
            this.Salary = salary;
        }

        public override string ToString() {
            return "ID:" + Id + "  Name:" + Name + "  Salary:" + Salary;
        }
    }
}

class SortBySalary : IComparer {
    public int Compare(object x, object y) {
        Employee ex = (Employee)x;
        Employee ey = (Employee)y;
        return ex.Salary.CompareTo(ey.Salary);
    }

Compare方法返回的是Salary比较的结果。

把比较器的示例作为参数传递给Sort方法,就可以实现该比较器。

输出结果:

ID:1 Name:Mary Salary:2800
ID:2 Name:Sam Salary:3000
ID:4 Name:July Salary:3200
ID:3 Name:Jick Salary:3800

 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面是泛型IComparable<T>和IComparer<T>示例,将员工信息放进一个List<Employee>中。

IComparable<T>:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IComparableTest3 {
    class Program {
        static void Main(string[] args) {
            var myList = new List<Employee>();
            myList.Add(new Employee(002, "Sam", 3000));
            myList.Add(new Employee(001, "Mary", 2800));
            myList.Add(new Employee(003, "Jick", 3800));
            myList.Add(new Employee(004, "July", 3200));
            myList.Sort();
            foreach (var e in myList)
            {
                Console.WriteLine(e.ToString());
            }
            Console.ReadKey();
        }
    }

    class Employee : IComparable<Employee> {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Salary { get; set; }

        public Employee(int id, string name, int salary) {
            this.Id = id;
            this.Name = name;
            this.Salary = salary;
        }

        public override string ToString() {
            return "ID:" + Id + "  Name:" + Name + "  Salary:" + Salary;
        }

        public int CompareTo(Employee e) {

            return this.Id.CompareTo(e.Id);
        }
    }
}


IComparer<T>:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IComparerTest1;

namespace IComparerTest1 {
    class Program {
        static void Main(string[] args) {
            var myList = new List<Employee>();
            myList.Add(new Employee(002, "Sam", 3000));
            myList.Add(new Employee(001, "Mary", 2800));
            myList.Add(new Employee(003, "Jick", 3800));
            myList.Add(new Employee(004, "July", 3200));
            myList.Sort(new SortBySalary());
            foreach (var e in myList)
            {
                Console.WriteLine(e.ToString());
            }
            Console.ReadKey();
        }
    }

    class Employee {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Salary { get; set; }

        public Employee(int id, string name, int salary) {
            this.Id = id;
            this.Name = name;
            this.Salary = salary;
        }

        public override string ToString() {
            return "ID:" + Id + "  Name:" + Name + "  Salary:" + Salary;
        }
    }
}

class SortBySalary : IComparer<Employee> {
    public int Compare(Employee ex,Employee ey) {
        return ex.Salary.CompareTo(ey.Salary);
    }

}

使用泛型避免了之前非泛型中object对Employee类型的拆箱过程,减少了不必要的性能损失。

猜你喜欢

转载自blog.csdn.net/qq_33413868/article/details/81396534
今日推荐