如何在没有 lambda 的情况下使用 linq 扩展?
这个例子纯粹是为了学习,不然我就直接用Lambda表达式了。
我想尝试使用没有 lambda 的Where() 扩展方法,只是为了看看它的外观,但我不知道如何让它编译并正常工作。这个例子毫无意义,所以不要费心去试图找出它的任何逻辑。
我基本上只是想知道是否可以在不使用 lambda 的情况下使用扩展方法(仅用于学习目的)以及代码中的样子。
我感到困惑的是,Where() 条件接受 Func
,但该方法返回 IEnumerable
? Func 的定义方式是,它接受一个 int 并返回一个 bool。如果这是 Func
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;
}
}
,我会收到以下错误:
No override for 'greaterThanTwo' matches delegate 'System .Func'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Where
接受一个函数,该函数接受单个元素(在本例中为int
)作为参数,并接受布尔值作为其返回类型。这称为谓词 - 它给出“是”或“否”答案,可以反复应用于相同类型的元素序列。您在
greaterThanTwo
函数中出错 - 它需要两个参数,而不是一个 - 并返回一个IEnumerable
- 因此它与Func
。它应该接受一个 int 并返回一个 bool - 同样,这是一个谓词(见上文)。一旦你解决了这个问题,你的另一个问题是
Invoke
- 你没有调用任何东西 - 你正在将委托(指针)交给一个方法,而内部Where
内部将在需要时调用它。试试这个:
Where
takes a function that accepts a single element (in this case,int
) as a parameter, and a boolean as its return type. This is called a predicate - it gives a "yes" or "no" answer that can be applied over and over again to a sequence of elements of the same type.You went wrong at the
greaterThanTwo
function - it takes two arguments, not one - and returns anIEnumerable<int>
- so it's totally incompatible withFunc<int, bool>
. It should take anint
and return abool
- again, this is a predicate (see above).Once you sort that out, your other problem is
Invoke
- you aren't invoking anything - you're handing off a delegate (pointer) to a method, and the guts inside ofWhere
will take care of invoking it when it needs.Try this:
定义
Func
定义了一个委托,该委托采用T
类型的单个参数并返回TResult
类型的结果。 LinqsWhere
子句是针对IEnumerable
定义的(通过扩展方法间接实现)并采用参数(Where
的基本版本)Func
类型,基本上表示函数必须采用IEnumerable
类型的参数并返回bool
值。为了使您的示例正常工作:
The definition
Func<T, TResult>
defines a delegate that takes a single parameter of typeT
and returns a result of typeTResult
. LinqsWhere
clause is defined (indirectly via an extension method) against anIEnumerable<T>
and takes a parameter (the basic version ofWhere
) of typeFunc<T, bool>
which basically says the function must take a parameter of the type of theIEnumerable
and return abool
value.To make your example work:
Func
表示您有一个接受 int 并返回 bool 的函数。如果您想在函数中使用更多参数,可以将它们列出来,但是您定义的最后一个泛型类型是该函数的返回类型。如果您想将其定义为 Func,您的方法将如下所示:Func>
您的函数应如下所示。Func<int, bool>
means that you have a function that takes in an int, and returns a bool. If you want to take more arguments into your function, you can list them out, however the last generic type that you define is the return type of that function. Your method would look something like this if you wanted to define it as a Func,Func<int, bool, IEnumerable<int>>
Your function should look something like this.Where()
函数对每个项目执行一次 lambda。如果您想返回,例如List
,您将使用Aggregate()
来代替它提供该功能。但是Where()
会根据 lambda 的布尔返回值自动添加或不添加项目。The
Where()
function executes the lambda once for every item. If you want to return, say aList<int>
you would useAggregate()
instead which provides that functionality. ButWhere()
automatically adds or doesn't add the item based on the boolean return value of your lambda.