繁体   English   中英

在c#中使用扩展方法与lambda表达式

[英]Using Extension methods versus lambda expression in c#

假设我有一个扩展方法

    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语法。

我认为你混淆了一些术语。 您显示的Filter方法是一个扩展方法(由参数列表中的this关键字指示。您称之为“linq语法”实际上是一个lambda表达式。

所有LINQ方法都实现为扩展方法,并支持两种调用“样式”:

  1. 实际上直接调用扩展方法就好像它们是被扩展类型的一部分一样。 这是您将其作为productEnum.Where(selectorParam)调用时显示的内容。

  2. 使用更类似SQL的语法,称为LINQ查询语法。 请记住,编译器会翻译这种类似SQL的语法,以实际调用扩展方法。

当你定义Func<Product, bool> languageFilter = prod => prod.Language == lang; ,您实际上是在定义一个lambda表达式并将其赋值给Func<Product, bool>类型的变量( languageFilter )。 Products.Where(q => q.Language == parameter); 语句完全相同,只是不是在变量中捕获lambda表达式而是将其简单地传递给扩展方法。

对于您的示例,要使用LINQ查询语法获得相同的结果,您可以将其编写为类似的

from p in Products
where p.Language == parameter

(假设参数在别处定义)

在内部,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)products.Filter(q => q.Price > parameter)

我认为如果框架中已经存在一个扩展方法来执行您想要的操作,请使用它。 'Where'方法也是一种扩展方法,而不是你写的方法。 我的理由是,“那些聪明的微软人可能比以往任何时候都做得更好”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM