先来看个小例子吧

  1. int[] intArray = new int[]{,,,,,};
  2. Array.Sort(intArray);
  3. Array.ForEach<int>(intArray,(i)=>Console.WriteLine(i));

这个例子定义了一个int数组,然后使用Array.Sort(arr)静态方法对此数组进行排序,最后输出排序后的数组。以上例子将毫无意外的依次输出1,2,3,4,5,6.

为什么Array的Sort方法可以正确的对int数组进行排序呢,我们自定义类可以吗?试试看,如下代码:

  1. public class Student
  2. {
  3. public int Age { get; set; }
  4.  
  5. public string Name { get; set; }
  6.  
  7. public int Score { get; set; }
  8. }
  9.  
  10. static void Main(string[] args)
  11. {
  12. Student[] students = new Student[]{
  13. new Student(){Age = ,Name="张三",Score=},
  14. new Student(){Age = ,Name="李四",Score=},
  15. new Student(){Age = ,Name="王五",Score=},
  16. new Student(){Age = ,Name="赵六",Score=},
  17. new Student(){Age = ,Name="司马",Score=},
  18. };
  19.  
  20. Console.WriteLine("--------------默认排序输出--------");
  21. Array.Sort(students);
  22. Array.ForEach<Student>(students,(s)=>Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}",s.Name,s.Age,s.Score)));
  23.  
  24. Console.Read();
  25. }

我们定义了Student类然后同样对他的数组进行排序,程序正确的编译通过,但是运行出错,运行时抛出了异常:System.InvalidOperationException{"Failed to compare two elements in the array."},这个异常的InnerException是ArgumentException{"At least one object must implement IComparable."};运行时异常说明:我们要使用Array.Sort(arr)静态方法,必须得保证数组中有一个元素实现IComparable接口。既然如此我们就让Student类实现IComparable接口.

  1. public class Student :IComparable
  2. {
  3. public int Age { get; set; }
  4.  
  5. public string Name { get; set; }
  6.  
  7. public int Score { get; set; }
  8.  
  9. /// <summary>
  10. /// 实现IComparable接口,用Age做比较
  11. /// </summary>
  12. /// <param name="obj">比较对象</param>
  13. /// <returns>比较结果</returns>
  14. public int CompareTo(object obj)
  15. {
  16. if (obj is Student)
  17. {
  18. return Age.CompareTo(((Student)obj).Age);
  19. }
  20.  
  21. return ;
  22. }
  23. }

在Student类中实现了IComparable接口,在CompareTo方法中比较Student的Age属性,这一次再次编译运行,程序正常的输出了按照年龄排序的Student数组。

假如说我们要对Student的Score属性进行排序该怎么办呢? Student类实现的IComparable接口只能按照一种属性排序呀。

这个是很容易实现的.net的类库开发者早为我们准备了另一个接口IComparer<T>接口用来实现比较类型T的两个实例。如下StudentScoreComparer类实现了对Student按照Score属性比较的IComparer<Student>

  1. public class StudentScoreComparer : IComparer<Student>
  2. {
  3. public int Compare(Student x, Student y)
  4. {
  5. return x.Score.CompareTo(y.Score);
  6. }
  7. }

现在我们可以使用下面代码对Student数组按照Score属性进行排序:

  1. Array.Sort(students, new StudentScoreComparer());
  2. Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}", s.Name, s.Age, s.Score)));

不过一个简单的按照Score属性排序,再定义一个类是不是有点大题小作呀,有没有更好的办法呢?当然有. .net为我们准备了比较对象大小的委托Comparison<T>我们可以使用拉姆达表达式或者匿名委托直接排序,如下代码实现:

  1. Array.Sort(students, (s1, s2) => s1.Score.CompareTo(s2.Score));
  2. Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}", s.Name, s.Age, s.Score)));

完整代码示例如下:

  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System.Text;
  4.  
  5. namespace SortingInCSharp
  6. {
  7. class Program
  8. {
  9. public class Student : IComparable
  10. {
  11. public int Age { get; set; }
  12.  
  13. public string Name { get; set; }
  14.  
  15. public int Score { get; set; }
  16.  
  17. /// <summary>
  18. /// 实现IComparable接口,用Age做比较
  19. /// </summary>
  20. /// <param name="obj">比较对象</param>
  21. /// <returns>比较结果</returns>
  22. public int CompareTo(object obj)
  23. {
  24. if (obj is Student)
  25. {
  26. return Age.CompareTo(((Student)obj).Age);
  27. }
  28.  
  29. return ;
  30. }
  31. }
  32.  
  33. static void Main(string[] args)
  34. {
  35. Student[] students = new Student[]{
  36. new Student(){Age = ,Name="张三",Score=},
  37. new Student(){Age = ,Name="李四",Score=},
  38. new Student(){Age = ,Name="王五",Score=},
  39. new Student(){Age = ,Name="赵六",Score=},
  40. new Student(){Age = ,Name="司马",Score=},
  41. };
  42.  
  43. Console.WriteLine("--------------默认排序输出--------");
  44. Array.Sort(students);
  45. Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}", s.Name, s.Age, s.Score)));
  46.  
  47. Console.WriteLine("----------按分数排序输出------------");
  48. Array.Sort(students, new StudentScoreComparer());
  49. Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}", s.Name, s.Age, s.Score)));
  50.  
  51. Console.WriteLine("----------按分数排序输出----------");
  52. Array.Sort(students, (s1, s2) => s1.Score.CompareTo(s2.Score));
  53. Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}", s.Name, s.Age, s.Score)));
  54.  
  55. Console.Read();
  56. }
  57.  
  58. public class StudentScoreComparer : IComparer<Student>
  59. {
  60. public int Compare(Student x, Student y)
  61. {
  62. return x.Score.CompareTo(y.Score);
  63. }
  64. }
  65. }
  66. }

总结:

在C#中有三个关于比较对象大小的接口,分别是IComparable、IComparable<T>和IComparer<T>。 IComparable和IComparable<T>是类本身实现的在实例之间比较大小的行为定义。IComparer<T>是定义在被比较类之外的专门比较两个T类型对象大小的行为,另外还有一个用于比较的委托定义Comparison<T>可以让我们用拉姆达表达式或者匿名委托或方法更方便的排序。

C#数组排序以及比较对象的大小的更多相关文章

  1. 如何精确地测量java对象的大小-底层instrument API

    转载: 如何精确地测量java对象的大小-底层instrument API 关于java对象的大小测量,网上有很多例子,大多数是申请一个对象后开始做GC,后对比前后的大小,不过这样,虽然说这样测量对象 ...

  2. C++一个类对象的大小计算

    计算一个类对象的大小时的规律: 1.空类.单一继承的空类.多重继承的空类所占空间大小为:1(字节,下同): 2.一个类中,虚函数本身.成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空 ...

  3. Ehcache计算Java对象内存大小

    在EHCache中,可以设置maxBytesLocalHeap.maxBytesLocalOffHeap.maxBytesLocalDisk值,以控制Cache占用的内存.磁盘的大小(注:这里Off ...

  4. 计算Java对象内存大小

    摘要 本文以如何计算Java对象占用内存大小为切入点,在讨论计算Java对象占用堆内存大小的方法的基础上,详细讨论了Java对象头格式并结合JDK源码对对象头中的协议字段做了介绍,涉及内存模型.锁原理 ...

  5. java 中对象比较大小

    java 中对象比较大小 java 中对象比较大小有两种方法 1:实现Comparable 接口 的 public int compareTo(T o) 方法: 2:实现Comparator 接口 的 ...

  6. Java对象的大小及应用类型

    基础类型数据的大小是固定的,对于非基本类型的java对象,其大小就值得商榷了.      在java中一个空Object对象的大小是8byte,这个大小只是保存堆中没有任何属性的对象的大小,看下面的语 ...

  7. C++类的实例化对象的大小之sizeof()

    之所以写这篇<C++类的实例化对象的大小之sizeof()>.是由于在參加笔试的时候遇到例如以下这么一道题,当时感觉就是这个一个坑,但.我还是义无反顾的跳了下去,由于存在知识点盲区啊.现, ...

  8. 准确计算Java中对象的大小

    由于在项目中需要大致计算一下对象的内存占用率(Hadoop中的Reduce端内存占用居高不下却又无法解释),因此深入学习了一下如何准确计算对象的大小. 使用system.gc()和java.lang. ...

  9. Java中计算对象的大小

    一.计算对象大小的方法 Java中如何计算对象的大小呢,找到了4种方法: 1.java.lang.instrument.Instrumentation的getObjectSize方法: 2.BTrac ...

随机推荐

  1. 15.VUE学习之-表单中使用key唯一令牌解决表单值混乱问题

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  2. 学习Spring框架系列(一):通过Demo阐述IoC和DI的优势所在

    Spring框架最核心东西便是大名鼎鼎的IoC容器,主要通过DI技术实现.下面我通过Demo的演变过程,对比学习耦合性代码,以及解耦和的过程,并深入理解面向接口编程的真正内涵. 这个例子包括如下几个类 ...

  3. B1066 图像过滤 (15分)

    B1066 图像过滤 (15分) 图像过滤是把图像中不重要的像素都染成背景色,使得重要部分被凸显出来.现给定一幅黑白图像,要求你将灰度值位于某指定区间内的所有像素颜色都用一种指定的颜色替换. 输入格式 ...

  4. 手机APP设计网

     http://hao.xueui.cn/ http://www.25xt.com/ 

  5. Less Css 教程

    http://www.w3cplus.com/css/less,这个东西太吊了!

  6. 成都大学CTF 网络攻防演练平台 WP

    web1 输入框那里鼠标右键,审查元素,删除maxlength web2 http://ctf.cdusec.org:8082/web2/?cdusec=tql web3 同上,用火狐hackbar或 ...

  7. xss games20关小游戏附源代码

    1. get方式的的值直接输出来了. ?name=<script>alert(1)</script> 2. 同样没有过滤,不过需要闭合前边的双引号和>. "&g ...

  8. python - 接口自动化测试 - ReadConfig - 读取配置文件封装

    # -*- coding:utf-8 -*- ''' @project: ApiAutoTest @author: Jimmy @file: read_config.py @ide: PyCharm ...

  9. Redis的 SORT命令

      SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC | DESC] [ALPHA] [S ...

  10. Halcon18 Linux For Armv7a 下载

    Halcon18 Linux For Armv7a 下载地址:http://www.211xun.com/download_page_16.html HALCON 18 是一套机器视觉图像处理库,由一 ...