假设我有一个扩展方法
public static IEnumerable<Product> Filter(
this IEnumerable<Product> productEnum,
Func<Product, bool> selectorParam)
{
return productEnum.Where(selectorParam);
}
我称之为
Func<Product, bool> languageFilter = prod => prod.Language == lang;
如果我没有被误删,其功能与
相同var products = Products.Where(q => q.Language == parameter);
我正在尝试了解何时可以根据第一个示例使用扩展方法,以及何时使用linq语法。
答案 0 :(得分:2)
我认为你混淆了一些术语。您显示的Filter
方法是一种扩展方法(由参数列表中的this
关键字指示。您称之为“linq语法”实际上是一个lambda表达式。
所有LINQ方法都作为扩展方法实现,并支持两种调用方式:
实际上直接调用扩展方法,就好像它们是被扩展类型的一部分一样。这是您在将其称为productEnum.Where(selectorParam)
时显示的内容。
使用更类似SQL的语法,称为LINQ查询语法。请记住,编译器会翻译这种类似SQL的语法,以实际调用扩展方法。
定义Func<Product, bool> languageFilter = prod => prod.Language == lang;
时,实际上是在定义lambda表达式并将其赋值给languageFilter
类型的变量(Func<Product, bool>
)。 Products.Where(q => q.Language == parameter);
语句完全相同,只是不是在变量中捕获lambda表达式而是将其简单地传递给扩展方法。
对于您的示例,要使用LINQ查询语法获得相同的结果,您可以将其写为类似于
from p in Products
where p.Language == parameter
(假设参数在别处定义)
答案 1 :(得分:1)
在内部,linq语法被分解为扩展方法,因此在功能上没有区别。
在你有一个Filter扩展方法的情况下,使用第一个表单可能没有多大意义。(我假设你的问题是不完整的,偶然)。但是,我们假设您需要在Filter方法中执行一些常用的逻辑,您不希望在where子句的每个实例中反复重复。在这种情况下,构建自定义扩展方法是有意义的,这样您就可以重用该逻辑。
例如,假设我们只使用未过期的产品(假设您的Product对象具有isExpired
属性)。既然,您可能会使用几个selectorParam值过滤这些未过期的产品进一步,您可以使用:
public static IEnumerable<Product> Filter(
this IEnumerable<Product> productEnum,
Func<Product, bool> selectorParam)
{
return productEnum.Where(x => !x.IsExpired).Where(selectorParam);
}
所以不要打电话给products.Where(x => !x.IsExpired).Where(q => q.Language == parameter)
或products.Where(x => !x.IsExpired).Where(q => q.Price > parameter)
products.Filter(q => q.Language == parameter)
。
答案 2 :(得分:1)
我认为如果框架中已经存在扩展方法来执行您想要的操作,请使用它。 'Where'方法也是一种扩展方法,而不是你写的方法。我的理由是,“那些聪明的微软人可能比以往任何时候都做得更好”。