бойтесь моего google-fu
$pdo = new PDO(
'mysql:host=mysql.example.com;dbname=example_db',
"username",
"password",
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
первый хит;)
Функция вызывается только один раз, чтобы вернуть IEnumerator
; после этого для перебора результатов используются метод MoveNext ()
и свойство Current
:
foreach (Foo f in GetFoos())
{
// Do stuff
}
в некоторой степени эквивалентно:
using (IEnumerator<Foo> iterator = GetFoos().GetEnumerator())
{
while (iterator.MoveNext())
{
Foo f = iterator.Current;
// Do stuff
}
}
Обратите внимание, что итератор расположен в конец - это особенно важно для удаления ресурсов из блоков итератора, например:
public IEnumerable<string> GetLines(string file)
{
using (TextReader reader = File.OpenText(file))
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
В приведенном выше коде вы действительно хотите, чтобы файл был закрыт, когда вы закончите итерацию, и компилятор хитро реализует IDisposable
, чтобы заставить это работать.
Нет .. функция будет вызвана один раз для получения IEnumerable .. а затем будет повторный вызов MoveNext и Current.
GetMyStrings () перенастраивает объект типа IEnumerable. Среда выполнения знает, как с этим бороться. Он вызывает IEnumerable.GetEnumerator (), а затем для этого объекта перечислителя вызывает MoveNext () и Current.