先来看个小例子吧

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

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

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

public class Student
{
public int Age { get; set; } public string Name { get; set; } public int Score { get; set; }
} static void Main(string[] args)
{
Student[] students = new Student[]{
new Student(){Age = ,Name="张三",Score=},
new Student(){Age = ,Name="李四",Score=},
new Student(){Age = ,Name="王五",Score=},
new Student(){Age = ,Name="赵六",Score=},
new Student(){Age = ,Name="司马",Score=},
}; Console.WriteLine("--------------默认排序输出--------");
Array.Sort(students);
Array.ForEach<Student>(students,(s)=>Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}",s.Name,s.Age,s.Score))); Console.Read();
}

我们定义了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接口.

public class Student :IComparable
{
public int Age { get; set; } public string Name { get; set; } public int Score { get; set; } /// <summary>
/// 实现IComparable接口,用Age做比较
/// </summary>
/// <param name="obj">比较对象</param>
/// <returns>比较结果</returns>
public int CompareTo(object obj)
{
if (obj is Student)
{
return Age.CompareTo(((Student)obj).Age);
} return ;
}
}

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

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

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

public class StudentScoreComparer : IComparer<Student>
{
public int Compare(Student x, Student y)
{
return x.Score.CompareTo(y.Score);
}
}

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

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

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

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

完整代码示例如下:

using System.Collections.Generic;
using System.Linq;
using System.Text; namespace SortingInCSharp
{
class Program
{
public class Student : IComparable
{
public int Age { get; set; } public string Name { get; set; } public int Score { get; set; } /// <summary>
/// 实现IComparable接口,用Age做比较
/// </summary>
/// <param name="obj">比较对象</param>
/// <returns>比较结果</returns>
public int CompareTo(object obj)
{
if (obj is Student)
{
return Age.CompareTo(((Student)obj).Age);
} return ;
}
} static void Main(string[] args)
{
Student[] students = new Student[]{
new Student(){Age = ,Name="张三",Score=},
new Student(){Age = ,Name="李四",Score=},
new Student(){Age = ,Name="王五",Score=},
new Student(){Age = ,Name="赵六",Score=},
new Student(){Age = ,Name="司马",Score=},
}; Console.WriteLine("--------------默认排序输出--------");
Array.Sort(students);
Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}", s.Name, s.Age, s.Score))); Console.WriteLine("----------按分数排序输出------------");
Array.Sort(students, new StudentScoreComparer());
Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}", s.Name, s.Age, s.Score))); Console.WriteLine("----------按分数排序输出----------");
Array.Sort(students, (s1, s2) => s1.Score.CompareTo(s2.Score));
Array.ForEach<Student>(students, (s) => Console.WriteLine(string.Format("{0}{1,2}岁了,他的分数是{2,3}", s.Name, s.Age, s.Score))); Console.Read();
} public class StudentScoreComparer : IComparer<Student>
{
public int Compare(Student x, Student y)
{
return x.Score.CompareTo(y.Score);
}
}
}
}

总结:

在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. Python装饰器使用规范案例详解

    由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25') ... >> ...

  2. psutil——获取系统信息的Python第三方模块

    本文摘自廖雪峰大神个人网站:https://www.liaoxuefeng.com/wiki/1016959663602400/1183565811281984 用Python来编写脚本简化日常的运维 ...

  3. 算法训练 Eurodiffusion

    Eurodiffusion /***********并未完全AC***********/ #include<iostream> #include<algorithm> #inc ...

  4. 动态规划:HDU2159-FATE(二维费用的背包问题)

    FATE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  5. Scrapy框架的命令行详解【转】

    Scrapy框架的命令行详解 请给作者点赞 --> 原文链接 这篇文章主要是对的scrapy命令行使用的一个介绍 创建爬虫项目 scrapy startproject 项目名例子如下: loca ...

  6. AngularJS 之1-初识

    摘要:本文主要记录第一次接触AngularJS的笔记,现在在我面前就是一张白纸+一点简单的html知识. 1.首先在<head>中加 <script src="一个网址(具 ...

  7. Go语言之反射(一)

    反射 反射是指在程序运行期对程序本身进行访问和修改的能力.程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分.在运行程序时,程序无法获取自身的信息.支持反射的语言可以在程序编译期将 ...

  8. java集群技术

    序言 越来越多的关键应用运行在J2EE(Java 2, Enterprise Edition)中,这些诸如银行系统和账单处理系统需要高的可用性(High Availability, HA),同时像Go ...

  9. 300万PV的ASP.NET网站使用阿里云的配置建议

    @老牛吃肉在博文“今天的访问高峰,扛过去了”的评论中询问了这样一个问题: 你好,站长,本公司正在考虑用阿里云.用途:互联网网站,主要站点:asp.net开发目前的考虑情况:访问ip 15-20万,pv ...

  10. C++模板编程-模板基础重点

    模板基础 1.模板参数自动推导,如果是已知的参数类型与个数,这调用模板时可以不写类型. Cout<<max<int>(1,3);可以写为Cout<<max(1,3) ...