在数组或者集合中对自定义类型进行排序分为两种方法。

1.如果这个自定义类型是自己定义编写的,那么我可以使它继承ICompareable<T>接口,实现其中的CompareTo(Object)方法。然后直接Array.Sort(排序对象数组)对其进行排序。

  1. class Book: IComparable<Book>
  2. {
  3. //defined name and number for book
  4. public string BookName { get; set; }
  5. public string BookNo { get; set; }
  6. // implement the CompareTo method
  7. public int CompareTo(Book other)
  8. {
  9. if (other == null) throw new ArgumentNullException("other");
  10. // compare to BookNo
  11. return this.BookNo.CompareTo(other.BookNo);
  12. }
  13. }

我自定义了一个Book类型。有BookName和BookNo属性。我使它继承了ICompareable<Book>接口。并且实现了CompareTo(Book)方法。这样,我就可以直接用Array.Sort()对

这个数组按BookNo进行排序。

  1. static void test2()
  2. {
  3. Book[] bookArray = {
  4. new Book{BookName = "AAA",BookNo = ""},
  5. new Book{BookName = "DDD",BookNo = ""},
  6. new Book{BookName = "CCC",BookNo = ""},
  7. new Book{BookName = "BBB",BookNo = ""},
  8. };
  9. Array.Sort(bookArray);
  10. foreach (Book item in bookArray)
  11. {
  12. Console.WriteLine("BookName = \"{0}\"; BookNo = \"{1}\".",item.BookName,item.BookNo);
  13. }
  14.  
  15. }

输出结果:

  1. BookName = "AAA"; BookNo = "".
  2. BookName = "BBB"; BookNo = "".
  3. BookName = "CCC"; BookNo = "".
  4. BookName = "DDD"; BookNo = "".

2.如果这个自定义类型不是自己编写的,是别人已经编写好的的一个类型,我不能修改这个类型。或者我想按照BookName排序,但是还不能修改现有的Book类该怎么办?

我们可以对这个类型进行包装。

  1. class Person
  2. {
  3. public string PersonName { get; set; }
  4. public string PersonAge {get;set;}
  5. }

Person这个类型没有继承ICompare接口。这个类不能修改,但是我还要对PersonAge进行排序。

我自己创建一个PersonCompare类,它实现了ICompare<T>接口,我把排序规则写在这个类中。

  1. class PersonCompare : IComparer<Person>
  2. {
  3. public int Compare(Person x, Person y)
  4. {
  5. if (x == null || y == null) throw new ArgumentNullException("argument error.");
  6. return x.PersonAge.CompareTo(y.PersonAge); //sort rule
  7. }
  8. }

测试:

  1. static void test3()
  2. {
  3. Person[] personArray = {
  4. new Person{PersonName = "AAA",PersonAge = ""},
  5. new Person{PersonName = "EEE",PersonAge = ""},
  6. new Person{PersonName = "CCC",PersonAge = ""},
  7. new Person{PersonName = "FFF",PersonAge = ""},
  8. };
  9. Array.Sort(personArray,new PersonCompare());//second parameter is sort rule
  10. foreach(Person item in personArray)
  11. {
  12. Console.WriteLine("PersonName = \"{0}\"; PersonAge = \"{1}\".", item.PersonName, item.PersonAge);
  13. }
  14. }

输出结果:

  1. PersonName = "AAA"; PersonAge = "".
  2. PersonName = "CCC"; PersonAge = "".
  3. PersonName = "EEE"; PersonAge = "".
  4. PersonName = "FFF"; PersonAge = "".

扩展:

如果我想对指定的属性进行排序怎么办?比如有的同事需要用PersonAge进行排序,有的需要使用PersonName进行排序。这种需求很常见。我们修改下PersonCompare方法。

为了使代码更加的规范。我建议以Person的属性为基础创建一个枚举。这个enum控制着我要按照那个属性进行排序。

  1. enum PersonType
  2. {
  3. PersonName,
  4. PersonAge
  5. }

我们需要PersonType作为参数传递给PersonCompare。以实现根据需求来定制排序规则。

  1. class PersonCompare : IComparer<Person>
  2. {
  3. private PersonType useType;
  4. public PersonCompare(PersonType pt)
  5. {
  6. this.useType = pt;
  7. }
  8. public int Compare(Person x, Person y)
  9. {
  10. if (x == null || y == null) throw new ArgumentNullException("argument error.");
  11. //return x.PersonAge.CompareTo(y.PersonAge);
  12. switch (useType){
  13. case PersonType.PersonAge:
  14. return x.PersonAge.CompareTo(y.PersonAge);
  15. case PersonType.PersonName:
  16. return x.PersonName.CompareTo(y.PersonName);
  17. default :
  18. throw new ArgumentNullException("Doesn't contain this type.");
  19. }
  20. }
  21. }

测试:

  1. static void test3()
  2. {
  3. Person[] personArray = {
  4. new Person{PersonName = "AAA",PersonAge = ""},
  5. new Person{PersonName = "EEE",PersonAge = ""},
  6. new Person{PersonName = "CCC",PersonAge = ""},
  7. new Person{PersonName = "FFF",PersonAge = ""},
  8. };
  9. Array.Sort(personArray,new PersonCompare(PersonType.PersonAge));// sort by age
  10. foreach(Person item in personArray)
  11. {
  12. Console.WriteLine("PersonName = \"{0}\"; PersonAge = \"{1}\".", item.PersonName, item.PersonAge);
  13. }
  14. Console.WriteLine("---------------------------------------------------");
  15. Array.Sort(personArray, new PersonCompare(PersonType.PersonName)); // sort by name
  16. foreach (Person item in personArray)
  17. {
  18. Console.WriteLine("PersonName = \"{0}\"; PersonAge = \"{1}\".", item.PersonName, item.PersonAge);
  19. }
  20. }

输出结果:

  1. PersonName = "CCC"; PersonAge = "".
  2. PersonName = "AAA"; PersonAge = "".
  3. PersonName = "EEE"; PersonAge = "".
  4. PersonName = "FFF"; PersonAge = "".
  5. ---------------------------------------------------
  6. PersonName = "AAA"; PersonAge = "".
  7. PersonName = "CCC"; PersonAge = "".
  8. PersonName = "EEE"; PersonAge = "".
  9. PersonName = "FFF"; PersonAge = "".

总结:

其实数组和集合的排序一样。如果对自己定义的类型数组或者集合排序就用IComareable<T>。如果要对已有的类型数组或者集合排序就用IComare<T>.

C#自定义类型数组排序的更多相关文章

  1. 《精通C#》自定义类型转化-扩展方法-匿名类型-指针类型(11.3-11.6)

    1.类型转化在C#中有很多,常用的是int类型转string等,这些都有微软给我们定义好的,我们需要的时候直接调用就是了,这是值类型中的转化,有时候我们还会需要类类型(包括结构struct)的转化,还 ...

  2. C#简单问题,不简单的原理:不能局部定义自定义类型(不含匿名类型)

    今天在进行代码测试时发现,尝试在一个方法中定义一个委托,注意是定义一个委托,而不是声明一个委托变量,在编写的时候没有报错,VS也能智能提示,但在编译时却报语法不完整,缺少方括号,但实际查询并没有缺少, ...

  3. Struts2框架的自定义类型转换器

    前言:对于java的基本数据类型及一些系统类(如Date类.集合类),Struts2提供了内置类型转换功能,但是也有一定的限制.所以就演示出自定义类型转换器 一.应用于局部类型转换器 eg.用户登录出 ...

  4. sruts2 自定义类型转换器

    1.1.1    Struts2中自定义类型转换器:(了解) 类型转换的过程是双向的过程: JSP---->Action参数提交:String---Date. Action---->JSP ...

  5. 一个关于自定义类型作为HashMap的key的问题

    在之前的项目需要用到以自定义类型作为HashMap的key,遇到一个问题:如果修改了已经存储在HashMap中的实例,会发生什么情况呢?用一段代码来试验: import java.util.HashM ...

  6. Struts2之自定义类型转换器

    Struts2自定义类型转换器分为局部类型转换器和全局类型转换器 (1)局部类型转换器 如果页面传来一个参数reg.action?birthday=2010-11-12到后台action,然后属性用d ...

  7. [原创]java WEB学习笔记67:Struts2 学习之路-- 类型转换概述, 类型转换错误修改,如何自定义类型转换器

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  8. 自定义类型转换器converter

    作用:目前将日期转换成string,将string转换成我想要的类型   0509课件里讲 一.数据类型转换在web应用程序中,数据存在两个方向上的转换:1.当提交表单时  表单数据以字符串的形式提交 ...

  9. 用SQLData读写数据库自定义类型

    如何读写自定义类型?SQLData是个很直观的解决办法 在oracle使用手册上找到了很好的资料 点击打开链接 http://docs.oracle.com/cd/B10501_01/java.920 ...

随机推荐

  1. [python学习篇 ] subprocess 子进程

    http://www.cnblogs.com/vamei/archive/2012/09/23/2698014.html

  2. poj 2499第K短路模板

    第k*短路模板(单项边) #include <iostream> #include <cstdio> #include <algorithm> #include & ...

  3. POJ 1609 Tiling Up Blocks

    Tiling Up Blocks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4675   Accepted: 1824 ...

  4. ECharts学习总结(二)-----图表组件漏斗图(funnel)

    今天在学习ECharts时,想要在ECharts图表的原生态Demo中抠出漏斗图,却不知如何下手,经过一番研究,特总结如下: 首先我们需要这样做 1.拷贝出两个js文件:esl.js 和echarts ...

  5. mybatis读取oracle中blob

    controller: byte[] blob = commonService.getPersonImage(bean.getIdCard()); String base64 = new String ...

  6. [转] Makefile 基础 (10) —— Makefile 后序

    该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客:(最原始版本) http://blog.csdn.net/haoel/article/details/2886 我转自 ...

  7. linux maven安装(三)

    1.下载maven http://maven.apache.org/download.cgi 我下载的是:apache-maven-3.3.9-bin.tar.gz 解压:tar -zxvf apac ...

  8. 【CF1015B】Obtaining the String(模拟)

    题意:给定两个字符串,每次可以交换相邻两个字符,给出任意一组交换次数小于1e4的方案使得a串成为b串,输出交换的次数与位置,无解输出-1 n<=50 思路:每次找到第一个不相同的字符,从后面找到 ...

  9. 快充 IC BQ25896 如何判斷 手機插著 adapter 充電器時,adapter Iout 大於限制,adapter Vout 小於 限制,導致 battery 不但沒充電且還需放電。

    若電池在 放電時,ICHGR 為0. 若電池在 充電時,ICHGR有變化.   下面有寫到 charge current 所以不是 discharge current   狀況:           ...

  10. unity3d各平台通讯原生的平台API的说明

    注意:unity3d与原生代码的调用需要pro版本,此点注意了. 一.IOS平台,由于IOS平台的原生应该是objectC,所以通讯起来非常的简单, 1.原生代码调用u3d代码: 1.1.在Xcode ...