2016-11-27 130 views
1
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); 
} 

MSDN給出了上面的代碼示例,我明白「digit」代表數組中的一個字符串。我不明白的是,Lambda表達式如何知道第二個參數是數組中字符串的索引。Lambda Expressing麻煩理解MSDN示例

+1

你所說的'know'意思?第二個參數包含索引,因爲這是通過'Where'傳遞給它的東西,就像第一個參數是源序列中的元素一樣。 – Lee

+0

因爲它在文檔中https://msdn.microsoft.com/zh-cn/library/bb549418(v=vs.110).aspx –

回答

1

lambda表達式總是由出兩個部分組成:

  • 在拉姆達操作者=>的前面是輸入參數(一個或多個)。在你的情況下,.Where操作給出一個字符串和一個稱爲(digit, index)的整數。
  • 之後lambda運算符是返回一個布爾(通過使用這兩個參數)的代碼。你也可以把它寫這樣的:

一切的一切,你可以瞭解expresison這樣的功能:

bool WhereDigits(string digit, int index) 
{ 
    return digit.Length < index; 
} 

手段,功能與比他們arrayindex下長度所有數字返回true。

0

那麼很簡單,因爲這個過載爲這樣的事情來實現(丟棄通用,使其更容易):

static IEnumerable<string> Where(string[] sequence, Func<string, int, bool> predicate) 
{ 
    int index = 0; 
    foreach(var item in sequence) 
    { 
     if (predicate(item, index)) 
      yield return item; 

     index++; 
    } 
} 

所以這個實現發送項目的索引到你的lambda表達式。

所以,你這樣稱呼它:

string[] digits = { "zero", "one", "two", "three", "four", 
        "five", "six", "seven", "eight", "nine" }; 

var result = Where(digits, PredicateMethod); 

這裏唯一的區別是,我轉換的拉姆達爲實際的方法:

static bool PredicateMethod(string digit, int index) 
{ 
    return digit.Length < index; 
} 
0

有該Where方法的兩個重載。其中一人需要Func<string, bool>,另一人需要Func<string, int, bool>。你在這裏打電話顯然是後者。

Func<string, int, bool>委託代表一個方法,它接受兩個參數(一個int和一個字符串)並返回一個bool。你的lambda表達式有兩個參數,並返回一個bool。因此代碼編譯。

現在,Where方法如何知道索引?

這調用了Where方法的內部運作。通過查看reference sourceWhere調用WhereIterator方法,該方法具有所有的索引的邏輯在它:

int index = -1; 
foreach (TSource element in source) { 
    checked { index++; } 
    if (predicate(element, index)) yield return element; 
} 
1

如何lambda表達式知道的是,第二個參數是字符串的數組中的索引

Lambda表達式不知道這一點。 Where擴展方法知道它是如何實現的。

Lambda只需要一些參數來完成您的工作。誰發送參數?您可以在下面看到Where擴展方法。

static IEnumerable<TSource> WhereIterator<TSource>(IEnumerable<TSource> source, Func<TSource, int, bool> predicate) { 
    int index = -1; 
    foreach (TSource element in source) { 
     checked { index++; } 

     if (predicate(element, index)) // the element and index is being sent to the function. your function executes here. 
      yield return element; 
    } 
} 

的參數,然後在這裏給運行代碼

(digit, index) => return digit.Length < index