Ta odpowiedź jest trochę bardziej techniczny ... Pamiętaj, że są po prostu lambdas syntatic skróty do anonimowi delegaci (które są metodami anonimowymi). Edycja: Mogą to być drzewa wyrażeń w zależności od podpisu Where
(patrz komentarz Marka).
list.Where((item, index) => index < list.Count - 1 && list[index + 1] == item)
funkcjonalnie równoważne
// inline, no lambdas
list.Where(delegate(item, index) { return index < list.Count - 1 && list[index + 1] == item; });
// if we assign the lambda (delegate) to a local variable:
var lambdaDelegate = (item, index) => index < list.Count - 1 && list[index + 1] == item;
list.Where(lambdaDelegate);
// without using lambdas as a shortcut:
var anonymousDelegate = delegate(item, index)
{
return index < list.Count - 1 && list[index + 1] == item;
}
list.Where(anonymousDelegate);
// and if we don't use anonymous methods (which is what lambdas represent):
function bool MyDelegate<TSource>(TSource item, int index)
{
return index < list.Count - 1 && list[index + 1] == item;
}
list.Where(MyDelegate);
Metoda Where
ma następujący podpis:
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate);
co odpowiada:
delegate bool WhereDelegate<TSource>(TSource source, int index);
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, WhereDelegate<TSource> predicate);
to jest gdzie zdefiniowany jest przedmiot i indeks.
Za kulisami Where
może zrobić coś takiego (tylko domyślać, można dekompilować, aby zobaczyć):
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
{
int index = 0;
foreach (TSource item in source)
{
if (predicate(index, source))
yield return item;
index++;
}
}
więc to, gdzie wskaźnik jest inicjowany i zostanie przeniesiony do swojego delegata (anonimowy, lambda, lub Inaczej).
Zwróć uwagę, że odnaleziono 'item' i' index'; wygląda na to, że zostało to naprawione przez edycję. –