自定义排序接口

时间:2021-07-04 22:11:09

我们习惯使用的Array和List类有时候经常需要使用排序,但是通常我们的对象都不可能只是一个简单的类型,而是一个复杂的类型,那么如何按照要求来进行排序呢?

当然Array.sort()和List.sort()大家肯定都会用了, 但是比如我现在有的是一个区分姓何名存储的人的姓名的对象呢?怎么按照姓排序,当姓相同时,然后按照名来排序呢?

这就需要用到IComparable比较接口了,它会自动生成一个CompareTo()的比较方法,具体的如下:

 class Person:IComparable<Person>
{
public string FirstName { get; set; }
public string LastName { get; set; }
/// <summary>
/// 自定义的比较类
/// 其实想法比较容易,自定义类里总有一些数值型数据,调用他们的CompareTo()就可以了啊。
///
/// </summary>
/// <param name="other"></param>
/// <returns></returns>
public int CompareTo(Person other)
{
//如果比较的是空就会报错
if (other == null) throw new ArgumentNullException("other");
//先进行比较姓
int result = this.LastName.CompareTo(other.LastName);
//如果姓相同,再比较名
if (result == 0)
{
result = this.FirstName.CompareTo(other.FirstName);
}
//返回结果
return result;
}

public override string ToString()
{
return String.Format("{0} {1}",FirstName,LastName);
}
}

使用的时候如何使用呢?如下:

List<Person> persons =new List<Person>()
{
new Person {FirstName="Damon",LastName="Hill" },
new Person {FirstName="Niki",LastName="Lauda" },
new Person {FirstName="Ayrton",LastName="Senna" },
new Person {FirstName="Graham",LastName="Hill" }
};
persons.Sort();
foreach(var p in persons)
{
Console.WriteLine(p);
}

就是这么简单,它就可以完全使用默认的比较接口来比较。略微扩充知识一下,在外文中LastName才是姓,FirstName是名。但是这样不能满足我们的需求啊,万一我们现在又要按照名来进行排序呢?或者说,我们要根据我们的需要,有时候用姓,有时候用名,这时候怎么办呢?只好单独写一个比较接口了。不过这种方法不是主要用来解决这个问题的,而是当原有的对象没有办法进行编码修改时,也就是说,不能够修改对象的数据结构时候,就需要用这种额外的方式来进行自定义排序了。具体代码如下:

 public enum PersonCompareType
{
FirstName,
LastName

}
/// <summary>
/// 这是一个比较器
/// </summary>
class PersonComparer : IComparer<Person>
{
private PersonCompareType compareType;
public PersonComparer(PersonCompareType compareType)
{
this.compareType = compareType;
}
/// <summary>
/// 这是继承的比较接口,
/// </summary>
/// <param name="x">对象1</param>
/// <param name="y">对象2</param>
/// <returns>1或者0或者-1</returns>
public int Compare(Person x, Person y)
{
if (x == null) throw new ArgumentNullException("x");
if (y == null) throw new ArgumentNullException("y");
switch (compareType)
{
case PersonCompareType.FirstName:
return x.FirstName.CompareTo(y.FirstName);
case PersonCompareType.LastName:
return x.LastName.CompareTo(y.LastName);
default:
throw new ArgumentException("unexpecter compare type");
}
}
}
这样就可以根据自己的需要来要求按照哪一属性来排序了。

List<Person> persons =new List<Person>()
{
new Person {FirstName="Damon",LastName="Hill" },
new Person {FirstName="Niki",LastName="Lauda" },
new Person {FirstName="Ayrton",LastName="Senna" },
new Person {FirstName="Graham",LastName="Hill" }
};
persons.Sort(new PersonComparer(PersonCompareType.FirstName));
foreach(var p in persons)
{
Console.WriteLine(p);
}

是不是很简单,其实,无论是Array还是List还是DataTable都可以按照这种想法来进行自定义排序。好了今天自定义排序接口就讲到这里了,再见。