2011-05-24 101 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

相關問題