1.2.1按名称对产品进行排序
//使用IComparer对ArrayList进行排序(C#1)
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.必须引入额外的类型来帮助排序(实现IComparer)
2.强制转换带来的问题——如果ArrayList中包含一个字符串,强制将string转为Product就会报错
代码知识点:
1.Product如果实现的是IComparable,就只能定义一种排序顺序
2.这里foreach循环会隐式将列表中每个元素转换为Product类型
//使用ICompare
对List
进行排序(C#2)
class ProductNameComparer : IComparer
{
public int Compare(Product x, Product y)
{
return x.Name.CompareTo(y.Name);
}
}
...
List
products=product.GetSampleProducts();
products.Sort(new ProductNameComparer());
foreach(Product product in products)
{
Console.WriteLine(product);
}
C#2中引入了泛型,避免了类型转换。
但是上面的代码还是需要实现接口来对产品进行排序,依靠委托可以解决这个问题。
//使用Comparison
对List
进行排序(C#2)
List
products=Product.GetSampleProducts();
products.Sort(delegate(Product x,Product y)
{ return x.Name.Compare(y.Name); }
);
foreach(Product product in products)
{
Console.WriteLine(product);
}
C#2同时引入了匿名方法,使代码更简洁
//在Lambda表达式中使用Comparision
进行排序(C#3)
List
products=Product.GetSampeProducts();
products.Sort((x,y) => x.Name.CompareTo(y.Name));
foreach(Product product in products)
{
Console.WriteLine(product);
}
C#3中引入了Lambda表达式,使委托的表达更加简洁优雅
//使用一个扩展方法对List
进行排序(C#3)
List
products=Product.GetSampleProducts();
foreach(Product product in products.OrderBy(p=>p.Name))
{
Console.WriteLine(product);
}
C#3中引入扩展方法,使得在不修改原始产品列表的前提下顺序打印产品名称
小结:C#1:弱类型比较功能、不支持委托排序—>C#2:强类型的比较功能、委托方法、匿名方法—>C#3:表达式、扩展方法、允许列表保持未排序状态
1.2.2查询集合
//循环、测试和打印(C#1)
List
products=Product.GetSampleProducts();
foreach(Product product in products)
{
if (product.Price > 10m)
{
Console.WriteLine(product);
}
}
//测试和打印分开进行(C#2)
List
products = Product.GetSampleProducts();
//Predicate表示定义一组条件并确定指定对象是否符合这些条件的方法
Predicate
test = delegate(Product P) { return P.Price > 10m; };
List
matches = products.FindAll(test);
//Action封装一个方法,这里使用了C#2方法组转换的特性
Action
print = Console.WriteLine;
matches.ForEach(print);
//测试和打印分开的另一个版本(C#2)
List
products=Product.GetSampleProducts();
products.FindAll(delegate(Product P) { return P.Price>10; }).ForEach(Console.WriteLine);
C#2:测试和打印任务分离
//用Lambda表达式来测试
List
products = Product.GetSampleProducts();
foreach(Product product in products.Where(p => p.Price > 10))
{
Console.WriteLine(product);
}
小结:C#1:条件和操作紧密耦合,两者都是硬编码的—>C#2:条件和操作分开,匿名方法使委托变得简单—>C#3:Lambda表达式使条件变得更容易阅读