您的位置:首页 > 其它

自定义类型数组排序的两种实现方式

2014-01-16 21:34 746 查看
Array类是C#中所有自定义类型数组的抽象类。这种自定义类型数组可以像String类型一样进行排序。这种排序的方法C#在基础类库中已经实现了,并且向外提供了可用的接口。只要按照C#中提供的方法就可以方便地实现自定义数组的排序。

方式一:

自定义类Person如下,想实现先按FirstName排序,再按LastName排序。如果Person类的代码可以修改的话,只要让Person类继承IComparable接口或IComparable<T>接口。该接口只提供了一个方法CompareTo(T),用这个方法返回一个Int值用以说明比较对象的大小。方法内的代码就是自定义的排序规则。

class Person
{
// 属性创建快捷键 Ctr+R,E
private string firstName;
private string lastName;

public string FirstName
{
get { return firstName; }
set { firstName = value; }
}

public string LastName
{
get { return lastName; }
set { lastName = value; }
}

public override string ToString()
{
return firstName + " " + lastName;
}
}


本例的自定义规则是先按FirstName排序,再按LastName排序,代码如下:

class Person : IComparable<Person>
{
private string firstName;
private string lastName;

public string FirstName
{
get { return firstName; }
set { firstName = value; }
}

public string LastName
{
get { return lastName; }
set { lastName = value; }
}
// IComparable<>接口实现
public int CompareTo(Person other)
{
if (other == null) throw new ArgumentNullException("other");

int result = String.Compare(firstName, other.firstName);
if (result == 0)
{
result = String.Compare(lastName, other.lastName);
}
return result;
}

public override string ToString()
{
return firstName + " " + lastName;
}
}


方式二:

有时已定义的类的代码允许修改或根本没有源代码只有DLL的时候,另一种方法就可以用了。这种方法是创建另一个自定义的继承IComparer接口或IComparer<T>接口的类,用来辅助自定义类的排序。该接口只提供了方法Compare(x,y)。(类似CompareTo(T)) 用这个方法返回一个Int值用以说明比较对象的大小。方法内的代码就是自定义的排序规则。。在辅助类PersonCompare中排序的规则定义了两条,一是先按LastName排序,再按FirstName排序,二是先按FirstName排序,再按LastName排序。并用了一个Enum枚举类来区分这两种排序。代码如下:

enum PersonCompareType
{
FirstName,
LastName
}

class PersonCompare : IComparer<Person>
{
private PersonCompareType compareType;

public PersonCompare(PersonCompareType compareType)
{
this.compareType = compareType;
}
// IComparer<>接口实现
public int Compare(Person x, Person y)
{
if (x == null) throw new ArgumentNullException("X");
if (y == null) throw new ArgumentNullException("Y");
int result = 0;
switch (compareType)
{
// 先按LastName排序
case PersonCompareType.LastName:
{
result = x.LastName.CompareTo(y.LastName);
if (result == 0)
{
result = x.FirstName.CompareTo(y.FirstName);
}
}
break;
// 先按FirstName排序
case PersonCompareType.FirstName:
{
result = x.FirstName.CompareTo(y.FirstName);
if (result == 0)
{
result = x.LastName.CompareTo(y.LastName);
}
}
break;
default:
{
throw new ArgumentException("unexpected compare type");
}
}
return result;
}
}


两种方式的使用如下:

static void Main(string[] args)
{
Person[] ps = { new Person { FirstName = "A", LastName = "C" },
new Person { FirstName = "C", LastName = "D" },
new Person { FirstName = "B", LastName = "A" }
};
Console.WriteLine("FirstName");
// 方式一 (先按FirstName排序)
Array.Sort(ps);
foreach (Person p in ps)
{
Console.WriteLine("{0}", p.ToString());
}
Console.WriteLine("LastName");
// 方式二 (先按LastName排序)
Array.Sort(ps, new PersonCompare(PersonCompareType.LastName));
foreach (Person p in ps)
{
Console.WriteLine("{0}", p.ToString());
}
Console.WriteLine("FirstName");
// 方式二 (先按FirstName排序)
Array.Sort(ps, new PersonCompare(PersonCompareType.FirstName));
foreach (Person p in ps)
{
Console.WriteLine("{0}", p.ToString());
}
Console.ReadKey();
}


使用Array类的两个Sort方法分别与上述两种方式相结合实现排序。方式一与只有自定义数组本身的Sort方法联合使用。方式二与有自定义数组和IComparer类型两个参数的Sort方法一起使用。其实自己只需要实现排序规则说明的方法。而具体用什么方法排序是由C#基础类库实现的(当然我们也可以根据需求自己实现)。C#基础类库中用的排序方法是QuickSort算法,有机会看看源代码。

结果如下:



参考:C# 高级编程(第7版)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐