接上一章功能,要求以一个特定的顺序显示一个列表。
功能实现:先将列表排好序,再遍历列表中的项。
在Net1.1中完成上述功能,就要求使用ArrayList.Sort。例子中要求提供一个IComparer 实现。
实现代码如下:
class ProductNameComparer:IComparer
{
public int Compare(object x, object y)
{
Product first = (Product)x;
Product second = (Product)y;
return first.Name.CompareTo(second.Name);
}
}
调用方式:
ArrayList products = Product.GetSampleProducts();
products.Sort(new ProductNameComparer());
foreach (Product product in products)
{
Console.WriteLine(product);
}
上述代码的问题在于
1、必须引入一个额外的类型来帮助排序【何解?object类型?】
2、Compare方法中存在强制类型转换,如果从Product.GetSampleProducts()中返回的ArrayList包含一个字符串,则运行时出错。
3、调用方式中,也进行了强制转换,即foreach会隐式的将列表中的每个元素转换为Product类。
C#2.0 改进后的代码
class ProductNameComparer:IComparer<Product>
{
public int Compare(Product first, Product second)
{
return first.Name.CompareTo(second.Name);
}
}
List<Product> products = Product.GetSampleProducts();
products.Sort(new ProductNameComparer());
foreach (Product product in products)
{
Console.WriteLine(product);
}
在2.0中,对产品名字的比较代码更为的简单。
1、不需要强制转换(提供比较的类型就为Product)
2、因为1,所以foreach存在的隐式的类型转换也被取消了。
如果不需要接口来进行比较,代码如下:
List<Product> products = Product.GetSampleProducts();
products.Sort(delegate(Product first, Product second)
{
return first.Name.CompareTo(second.Name);
});
foreach (Product product in products)
{
Console.WriteLine(product);
}
采用创建委托实例的方法,将这个委托提供给Sort方法比较。
C# 3.0中可以将匿名方法转换为更简洁的创建委托实例的方式
List<Product> products = Product.GetSampleProducts();
products.Sort(
(first,Second)=>first.Name.CompareTo(Second.Name) //Lambda 表达式
);
foreach(Product product in products)
{
Console.WriteLine(product);
}
说明:采用Lambda表达式,虽仍然会创建一个Comparison<Product>委托,但代码量更少了,而且不需要使用delegate关键字来引入委托了,甚至不需要制定参数类型。
其他的排序方法
List<Product> products = Product.GetSampleProducts();
foreach (Product product in products.OrderBy(p => p.Name))
{
Console.WriteLine(product);
}
说明:采用OrderBye方法。【Linq?】
图示说明: