如何在没有lambda的情况下使用linq扩展?

时间:2011-05-24 23:05:49

标签: c# linq lambda

这个例子纯粹是为了学习,否则我会马上使用Lambda表达式。

我想尝试使用没有lambda的Where()扩展方法只是为了看看它看起来如何,但我无法弄清楚如何让它编译和正常工作。这个例子毫无意义,所以不要试图找出任何逻辑。

我基本上只是想知道是否可以在不使用lambda的情况下使用扩展方法(仅用于学习目的)以及代码中的结果。

我感到困惑的是Where()条件在Func<int,bool>中所占用,但该方法返回IEnumerable<int>?定义Func的方式,它接受一个int并返回一个bool。如果这是Func<int, bool, IEnumberable<string>>

,那对我来说会更有意义
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Delegates
{
    public class Learning
    {
        /// <summary>
        /// Predicates - specialized verison of Func
        /// </summary>
        public static void Main()
        {
            List<int> list = new List<int> { 1, 2, 3 };

            Func<int, bool> someFunc = greaterThanTwo;
            IEnumerable<int> result = list.Where(someFunc.Invoke(1));

        }


        static IEnumerable<int> greaterThanTwo(int arg, bool isValid)
        {
              return new List<int>() { 1 };
        }

    }
}

更新代码

public class Learning
    {
        /// <summary>
        /// Predicates - specialized verison of Func
        /// </summary>
        public static void Main()
        {
            // Without lambda
            List<int> list = new List<int> { 1, 2, 3 };

            Func<int, bool> someFunc = greaterThanTwo;
            // predicate of type int
            IEnumerable<int> result = list.Where(someFunc);

        }


        static bool greaterThanTwo(int arg, bool isValid)
        {
            return true;
        }

    }

我收到以下错误:

'greaterThanTwo'没有重载符合委托'System.Func'

4 个答案:

答案 0 :(得分:5)

Where接受一个函数,该函数接受单个元素(在本例中为int)作为参数,并将boolean作为其返回类型。这称为谓词 - 它给出了“是”或“否”的答案,可以一遍又一遍地应用于相同类型的元素序列。

你在greaterThanTwo函数出错了 - 它需要两个参数,而不是一个 - 并返回一个IEnumerable<int> - 因此它与Func<int, bool>完全不兼容。它应该是int并返回bool - 再次,这是一个谓词(见上文)。

一旦你解决了这个问题,你的另一个问题是Invoke - 没有调用任何东西 - 你将一个委托(指针)交给一个方法,然后是胆量Where内部将在需要时负责调用它。

试试这个:

static bool greaterThanTwo(int arg)
{
    return (arg > 2);
}

//snip

Func<int, bool> someFunc = greaterThanTwo;
IEnumerable<int> result = list.Where(someFunc);

答案 1 :(得分:3)

定义Func<T, TResult>定义了一个委托,它接受类型T的单个参数并返回类型TResult的结果。 Linqs Where子句是针对IEnumerable<T>(通过扩展方法间接)定义的,并且采用Where类型的参数(Func<T, bool>的基本版本),它基本上表示函数必须使用IEnumerable类型的参数并返回bool值。

使您的示例有效:

bool greaterThanTwo(int arg)
{
    // this needs to be a boolean operation against the arg
    return arg > 2;
}

// and invoke like
list.Where(greaterThanTwo);

答案 2 :(得分:1)

Func<int, bool>表示你有一个接受int的函数,并返回一个bool。如果要在函数中加入更多参数,可以将它们列出,但是您定义的最后一个泛型类型是该函数的返回类型。如果你想将它定义为Func,你的方法看起来像这样,Func<int, bool, IEnumerable<int>>你的函数应该看起来像这样。

namespace Delegates
{
    public class Learning
    {
        /// <summary>
        /// Predicates - specialized verison of Func
        /// </summary>
        public static void Main()
        {
            List<int> list = new List<int> { 1, 2, 3 };

            Func<int, bool> someFunc = greaterThanTwo;
            IEnumerable<int> result = list.Where(someFunc);

        }


        static bool greaterThanTwo(int arg)
        {
              return (arg > 2);
        }

    }
}

答案 3 :(得分:0)

Where()函数为每个项执行一次lambda。如果您想要返回,请说List<int>,而是使用Aggregate()来提供该功能。但是Where()会根据lambda的布尔返回值自动添加或不添加项目。