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

本文关键字:情况下 linq 扩展 lambda | 更新日期: 2023-09-27 17:57:46

这个例子纯粹是为了学习,否则我会立即使用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"匹配

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

Where接受一个接受单个元素(在本例中为int)的函数作为参数,并将布尔值作为其返回类型。这被称为谓词——它给出了一个"是"或"否"的答案,可以反复应用于相同类型的元素序列。

您在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);

定义Func<T, TResult>定义了一个委托,该委托接受T类型的单个参数并返回TResult类型的结果。Linqs Where子句是针对IEnumerable<T>定义的(通过扩展方法间接地),并接受类型为Func<T, bool>的参数(Where的基本版本),这基本上意味着函数必须接受类型为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);

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);
        }
    }
}

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