mvc(4)使用Lambna表达式(过滤扩展方法)
我们可以使用一个委托,以使上述FilterByCategory方法更通用,这样,针对每个Product进行条用委托,可以以所选择的任何方式来过滤对象。
代码如下:
using System; using System.Collections.Generic; namespace MyProject.Models { public static class MyExtensionMethods{ public static decimal TotalPrices(this IEnumerable<Product> productEnum) { decimal total=0; foreach(Product prod in productEnum) { total+=prod.Price; } return total; } public static IEnumerable<Product> FilterByCategory(this IEnumerable<Product> productEnum,string categoryParam) { foreach(Product prod in productEnum) { if(prod.Category==categoryParam) { yield return prod; } } } public static IEnumerable<Product> Filter(this IEnumerable<Product> productEnum,Func<Product,bool> selectorParam) { foreach(Product prod in productEnum) { if(selectorParam(prod)) { yield return prod; } } } } }
这个代码中使用了一个Func作为过滤参数,简单解释下这个(需要详细了解可以自己查资料),该委托有一个Product参数,并返回一个布尔值,如果Product匹配结果,则返回ture;
下面演示如何调用,代码如下:
public ViewResult UserFileterExtensionMethod() { IEnumerable<Product> products =new ShoppingCart { Products=new List<Product>{ new Product{Name="Kayak",Category="Watersports",Price=275M}, new Product{Name="LiseJacket",Category="Watersports",Price=48.95M}, new Product{Name="Soccer ball",Category="Soccer",Price=19.50M}, new Product{Name="Conner flag",Category="Soccer",Price=34.95M} } }; Func<Product,bool> categoryFilter =delegate(Product prod) { return prod.Category="Soccer"; }; decimal total=0; foreach(Product prod in products.Filter(categoryFilter)) { total+=prod.Price; } return View("Result",(object)String.Format("Total:{0}",total)); }
这样我们的代码通用性就更强了一点,现在,可以用这个委托中指定的任何条件来过滤Product对象,但是有一个问题,我们必须为要用到的每一种过滤定义一个Func,这样代码
的简洁高效没体现。但是我们有一个方法,可以用Lambda表达式,
代码如下:
public ViewResult UserFileterExtensionMethod() { IEnumerable<Product> products =new ShoppingCart { Products=new List<Product>{ new Product{Name="Kayak",Category="Watersports",Price=275M}, new Product{Name="LiseJacket",Category="Watersports",Price=48.95M}, new Product{Name="Soccer ball",Category="Soccer",Price=19.50M}, new Product{Name="Conner flag",Category="Soccer",Price=34.95M} } }; Func<Product,bool> categoryFilter=prod=>prod.Category=="Soccer"; decimal total=0; foreach(Product prod in products.Filter(categoryFilter)) { total+=prod.Price; } return View("Result",(object)String.Format("Total:{0}",total)); }
让我们试试代码更紧凑吧,代码如下
public ViewResult UserFileterExtensionMethod() { IEnumerable<Product> products =new ShoppingCart { Products=new List<Product>{ new Product{Name="Kayak",Category="Watersports",Price=275M}, new Product{Name="LiseJacket",Category="Watersports",Price=48.95M}, new Product{Name="Soccer ball",Category="Soccer",Price=19.50M}, new Product{Name="Conner flag",Category="Soccer",Price=34.95M} } }; decimal total=0; foreach(Product prod in products.Filter(prod=>prod.Category=="Soccer")) { total+=prod.Price; } return View("Result",(object)String.Format("Total:{0}",total)); }
我们也可以用Lambda表达式结果部分的方式来组合多个过滤
代码如下:
public ViewResult UserFileterExtensionMethod() { IEnumerable<Product> products =new ShoppingCart { Products=new List<Product>{ new Product{Name="Kayak",Category="Watersports",Price=275M}, new Product{Name="LiseJacket",Category="Watersports",Price=48.95M}, new Product{Name="Soccer ball",Category="Soccer",Price=19.50M}, new Product{Name="Conner flag",Category="Soccer",Price=34.95M} } }; decimal total=0; foreach(Product prod in products.Filter(prod=>prod.Category=="Soccer" ||prod.Price>20)) { total+=prod.Price; } return View("Result",(object)String.Format("Total:{0}",total)); }
由上面的例子可以看出Lambda表达式是一种比价清晰的表达方式,可读性也比较强,相对SQL简单很多。