二、排序Product
1.按名称对产品进行排序,以特定顺序显示一个列表的最简单方式就是先将列表排序,再遍历并显示其中的项。
C#1.1 使用IComparer对ArrayList进行排序
product类
using System.Collections;
using System.ComponentModel; namespace Chapter01.CSharp1
{
[Description("Listing 1.01")]
public class Product
{
string name;
public string Name
{
get { return name; }
} decimal price;
public decimal Price
{
get { return price; }
} public Product(string name, decimal price)
{
this.name = name;
this.price = price;
} public static ArrayList GetSampleProducts()
{
ArrayList list = new ArrayList();
list.Add(new Product("West Side Story", 9.99m));
list.Add(new Product("Assassins", 14.99m));
list.Add(new Product("Frogs", 13.99m));
list.Add(new Product("Sweeney Todd", 10.99m));
return list;
} public override string ToString()
{
return string.Format("{0}: {1}", name, price);
}
}
}
ArrayListSort类
using System;
using System.Collections;
using System.ComponentModel; namespace Chapter01.CSharp1
{
[Description("Listing 1.05")]
class ArrayListSort
{
class ProductNameComparer : IComparer
{
public int Compare(object x, object y)
{
Product first = (Product)x;
Product second = (Product)y;
return first.Name.CompareTo(second.Name);
}
} static void Main()
{
ArrayList products = Product.GetSampleProducts();
products.Sort(new ProductNameComparer());
foreach (Product product in products)
{
Console.WriteLine(product);
}
}
}
}
提供一个IComparer实现,比较器。或者Product类实现IComparable。
区别:IComparer和IComparable(比较器接口和可比较的接口)
缺陷:Compare方法中显示强制类型转换,而ArrayList是类型不安全的,转换为对象Product时可能报错。foreach循环中隐式的编译器自动类型转换,转换为Product类型执行时可能报错。
2.C#2.0 引入泛型,使用IComparer<Product>对List<Product>进行排序
product类
using System.Collections.Generic;
using System.ComponentModel; namespace Chapter01.CSharp2
{
[Description("Listing 1.02")]
public class Product
{
string name;
public string Name
{
get { return name; }
private set { name = value; }
} decimal price;
public decimal Price
{
get { return price; }
private set { price = value; }
} public Product(string name, decimal price)
{
Name = name;
Price = price;
} public static List<Product> GetSampleProducts()
{
List<Product> list = new List<Product>();
list.Add(new Product("West Side Story", 9.99m));
list.Add(new Product("Assassins", 14.99m));
list.Add(new Product("Frogs", 13.99m));
list.Add(new Product("Sweeney Todd", 10.99m));
return list;
} public override string ToString()
{
return string.Format("{0}: {1}", name, price);
}
}
}
ListSortWithComparer类
using System;
using System.Collections.Generic;
using System.ComponentModel; namespace Chapter01.CSharp2
{
[Description("Listing 1.06")]
class ListSortWithComparer
{
class ProductNameComparer : IComparer<Product>
{
public int Compare(Product first, Product second)
{
return first.Name.CompareTo(second.Name);
}
} static void Main()
{
List<Product> products = Product.GetSampleProducts();
products.Sort(new ProductNameComparer());
foreach (Product product in products)
{
Console.WriteLine(product);
}
}
}
}
使用Comparison<Product>对List<Product>进行排序(C#2),不需要实现ProductNameComparer比较器类型,只是创建一个委托实例(C#2.0 匿名方法)。
using System;
using System.Collections.Generic;
using System.ComponentModel; namespace Chapter01.CSharp2
{
[Description("Listing 1.07")]
class ListSortWithComparisonDelegate
{
static void Main()
{
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);
}
}
}
}
3.C#3.0 Lambda表达式 在Lambda表达式中使用Comparison<Product>进行排序(C#3)
product类
using System.Collections.Generic;
using System.ComponentModel; namespace Chapter01.CSharp3
{
[Description("Listing 1.3")]
class Product
{
public string Name { get; private set; }
public decimal Price { get; private set; } public Product(string name, decimal price)
{
Name = name;
Price = price;
} Product()
{
} public static List<Product> GetSampleProducts()
{
return new List<Product>
{
new Product { Name="West Side Story", Price = 9.99m },
new Product { Name="Assassins", Price=14.99m },
new Product { Name="Frogs", Price=13.99m },
new Product { Name="Sweeney Todd", Price=10.99m}
};
} public override string ToString()
{
return string.Format("{0}: {1}", Name, Price);
}
}
}
ListSortWithLambdaExpression类
using System;
using System.Collections.Generic;
using System.ComponentModel; namespace Chapter01.CSharp3
{
[Description("Listing 1.08")]
class ListSortWithLambdaExpression
{
static void Main()
{
List<Product> products = Product.GetSampleProducts();
products.Sort(
(first, second) => first.Name.CompareTo(second.Name)
);
foreach (Product product in products)
{
Console.WriteLine(product);
}
}
}
}
ListOrderWithExtensionMethod类 使用扩展方法对List<Product>进行排序
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; namespace Chapter01.CSharp3
{
[Description("Listing 1.09")]
class ListOrderWithExtensionMethod
{
static void Main()
{
List<Product> products = Product.GetSampleProducts(); foreach (Product product in products.OrderBy(p => p.Name))
{
Console.WriteLine(product);
}
}
}
}
总结:
→C#1,弱类型的比较功能不支持委托排序。
→C#2,强类型的比较功能,委托比较,匿名方法。
→C#3Lambda表达式,扩展方法,允许列表保持未排序状态。