这个例子纯粹是为了学习,否则我会立即使用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"匹配
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的布尔返回值自动添加或不添加项。