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

时间:2011-09-02 04:47:00

标签: c# linq lambda

假设我有一个扩展方法

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

3 个答案:

答案 0 :(得分:2)

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

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

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

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

  3. 定义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)

你可以使用:
<{1}}和products.Filter(q => q.Language == parameter)

答案 2 :(得分:1)

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