2012-07-10 39 views
3

我不確定這是否是正確的地方問這個,我很抱歉,如果不是。使用試圖瞭解使用c的LINQ代碼#

相同的代碼爲:

C# LINQ expression question

string[] digits = { "zero", "one", "two", "three", "four", "five", 
        "six", "seven", "eight", "nine" }; 
var shortDigits = digits.Where((digit, index) => digit.Length < index); 
foreach (var sD in shortDigits) 
{ 
    Console.WriteLine(sD); 
} 
// Output: 
// five 
// six 
// seven 
// eight 
// nine 

系統如何知道,digit是數字的項目,index在陣列中的位置?

+0

nope,它的工作方式,請參閱:http:// msdn.microsoft.com/en-us/library/bb311046.aspx? – Somebody 2012-07-10 16:12:03

回答

6

Where擴展方法的特定超載被定義爲接受Func,其中第一個參數是元素,第二個參數是該元素的索引。

謂詞

類型:這是在documentation明確提到System.Func<TSource, Int32, Boolean>

的一種功能測試 一個條件的每個源元件; 函數 函數的第二個參數表示源元素的索引。

強調我的。

+0

這就是我正在尋找的答案,thx – Somebody 2012-07-10 16:18:35

2

這只是一個命名的事情,你可以命名數字任何東西,並索引任何東西。這僅僅是一個匿名函數lambda表達式......它可以被改寫:

(string digit, int index) => digit.Length < index 

所以,名字是一樣的,你通常設置在一個方法的任何參數。對於被C#引擎識別的名稱沒有什麼特別的。

(string index, int digit) => index.Length < digit 

上面的工作也會......這會令人困惑,但它會奏效。這只是表明該名稱可以是任何你想要的

如果你指如何簽名本身那麼它是由於overload of the Where function

public static IEnumerable<TSource> Where<TSource>(
    this IEnumerable<TSource> source, 
    Func<TSource, int, bool> predicate 
) 

所以,TSource在這種情況下是string,使得Func變成Func<string, int, bool>。這意味着拉姆達必須採取string參數後跟int PARAM,並返回一個bool

+0

他的問題是關於爲什麼第一個參數代表集合中的項目,第二個參數代表它們的索引...而不是它們的名稱。 – 2012-07-10 16:12:57

+0

我可以閱讀它,所以將等待OP澄清...同時我會回答兩種可能性 – 2012-07-10 16:14:58

+0

正確的傑夫,但感謝解釋賈斯汀:) – Somebody 2012-07-10 16:16:13

0

因爲有以作謂語這樣的功能的where過載:

Func<TSource, int, bool> 

語義的這個謂詞ios定義了第二個參數就是索引。所以如果你傳遞一個帶有兩個參數的lambda表達式,那麼這個lambda表達式就會被調用。

1

Where所使用的過載來實現這樣的:

public static IEnumerable<T> Where<T>(
     this IEnumerable<T> list, Func<T,int,bool> predicate) 
{ 
    int num = -1; 
    foreach (T current in list) 
    { 
     num++; 
     if (predicate(current, num)) 
     { 
     yield return current; 
     } 
    } 
    yield break; 
} 

,你可以看到,在每次迭代中,謂詞(即,通過lambda表達式)被調用傳遞的當前元素列表和當前索引。

這樣,lambda表達式中的代碼就知道元素及其索引。