Я думаю, что Джон довольно хорошо объясняет это в своей статье, но это объяснение основано на том, что вы понимаете, как компилятор генерирует код при наличии оператора yield
.По сути, происходит то, что компилятор генерирует итератор, который не вызывается (отложенное выполнение) до тех пор, пока не потребуется один из элементов итерации.Первоначальный метод содержит как код, который проверяет аргументы, так и код итерации.Компилятор связывает все это в итератор, который, помните, не вызывается, пока не понадобится первый элемент.Это означает, что проверка не произойдет, пока вы не попытаетесь получить доступ к одному из элементов перечислимого.
Разделив его на два метода, один из которых содержит проверку, а другой - блок итератора, он гарантирует, что проверка правильностикод запускается при создании итератора, а не при его выполнении.Это потому, что единственный код, связанный с итератором, это код второго метода;это единственный код, выполнение которого отложено.Код проверки выполняется во время создания итератора.