2011-05-24 100 views
2

这个例子纯粹是为了学习,否则我会马上使用Lambda表达式。如何在不使用lambda的情况下使用linq扩展?

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

我基本上只想知道是否可以使用扩展方法而不使用lambda(仅用于学习目的)以及代码中的外观如何。

我所困惑的是Where()条件需要Func<int,bool>,但该方法返回IEnumerable<int>? Func的定义方式是,它接受一个int并返回一个布尔值。它将使我更有意义,如果这是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 '

+0

看看这篇文章从MSDN。 http://msdn.microsoft.com/en-us/library/bb534803.aspx – 2011-05-24 23:10:33

+0

如果您更新您的方法签名以匹配Func的委托语法,您可能可以通过此方式传递它。 – 2011-05-24 23:12:17

回答

5

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); 
+0

我尝试使用int作为参数并返回一个布尔值,但它抱怨返回类型不是IEnumberable 。我已经更新了我的示例以使用Func chobo 2011-05-24 23:10:30

+0

哦,我明白了。我没有删除布尔参数。令我困惑的是Where()表示一个IEnumberable返回类型这就是为什么我使用额外参数我的Func – chobo 2011-05-24 23:16:00

0

Where()函数执行一次拉姆达为每个项目。如果你想返回,说一个List<int>你会使用Aggregate(),而不是它提供的功能。但Where()自动添加或不添加基于lambda的布尔返回值的项目。

1

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

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

    } 
} 
+0

你到底是谁:) – 2011-05-24 23:16:02

+0

你偷了我的twitter处理和我的域名:(我不得不使用@rexmorgan,而不是@rexm – 2011-05-24 23:16:38

3

定义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); 
+0

很好的例子!有没有一种方法使用这种方法与2输入参数? – fubo 2014-08-20 10:13:11

相关问题