2014-07-27 3 views
1

Я читаю, что происходит, когда CLR выполняет метод SkipWhile. Например, позволяет считать, что:понимание реализации метода SkipWhileIterator

IList<string> numbers = new List<string>() 
{ 
"One","Two","Three", "Four","Five" 
}; 
var result = numbers.SkipWhile(number => number.Length == 3); 
result.ToList().ForEach(number => Console.WriteLine(number)); 

CLR будет делать следующие шаги:

C# компилятор создает метод <Main>b__1 с помощью анонимного метод (number => number.Length == 3) в момент компиляции. CLR будет экземпляр экземпляра MulticastDelegate с использованием метода <Main>b__1 в качестве предиката для SkipWhile. CLR создает экземпляр итератора SkipWhileIterator с использованием исходного списка и предиката <Main>b__1. В связи с отсроченным исполнением , SkipWhileIterator не будет выполняться до CLR вызывает ToList или использует метод ForEach для итерации . CLR выполняет метод ToList над SkipWhileIterator возвращения из метода SkipWhile и внутри SkipWhileIterator, в CLR перебирает исходный список один один и выполняет предикат над каждым из пунктов. Если предикат возвращает значение false, то SkipWhileIterator возвращает этот элемент в результате метода SkipWhile; или если он возвращает true, , то он продолжается по списку, пока он не закончится.

До сих пор все в порядке.

Но, я наблюдал за реализацией SkipWhileIterator от this web site.

static IEnumerable<TSource> SkipWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate) { 
     bool yielding = false; 
     foreach (TSource element in source) { 
      if (!yielding && !predicate(element)) yielding = true; 
      if (yielding) yield return element; 
     } 
} 

Но, разве это не ложь? По моему мнению, второй, если заявление должно быть так:

if (yielding) {yielding=false; yield return element}; 

Yielding «s значение необходимо установить ложные во втором случае, в противном случае он не будет получать внутри первого, если утверждение, если значение True.

Спасибо.

ответ

1

Как только SkipWhile находит значение, которое не соответствует предикату, оно перестает смотреть и просто возвращает остальную часть последовательности. yielding начинается с false, так что элементы не будут возвращены, а в первом не совпадении установлено значение true. После этого не нужно , чтобы снова войти в первый оператор if, потому что он уже знает, что он вернет элементы после этого.

+0

У меня есть смысл в методе SkipWhile. У меня есть это, он вернет все элементы в списке, которые не соответствуют условию. Но, кажется, SkipWhile обходит элементы в последовательности, если указанное условие истинно, а затем возвращает остальные элементы. –

+0

есть. о чем вы говорите, это просто «где» с отрицательным предикатом. –

+0

Верно, моя вина. Еще раз спасибо. –

1

Я думаю, вам нужно прочитать документацию метода, чтобы понять логику:

От Enumerable.SkipWhile:

Пропускает элементы в последовательности, пока заданное условие истинно и затем возвращает оставшиеся элементы.

yielding не установлен в false еще раз, потому что желаемое поведение. Предикат должен быть сопоставлен только

+0

Да, я понял. Я не обратил внимания на то, что я читал книгу. –

Смежные вопросы