<p>Le mot-clé contextuel <code>yield</code> fait en réalité beaucoup de choses ici.</p>
<p>La fonction retourne un objet qui implémente l’interface <code>IEnumerable<object></code>. Si une fonction appelante commence à itérer (<code>foreach</code>) sur cet objet, la fonction est appelée à nouveau jusqu’à ce qu’elle « cède » (yield). C’est du sucre syntaxique introduit dans <strong>C# 2.0</strong>. Dans les versions antérieures, vous deviez créer vos propres objets <code>IEnumerable</code> et <code>IEnumerator</code> pour faire ce genre de choses.</p>
<p>La façon la plus simple de comprendre ce type de code est de saisir un exemple, de placer des points d’arrêt et de voir ce qui se passe. Essayez de parcourir pas à pas cet exemple :</p>
<pre><code class="lang-auto">public void Consumer()
{
foreach(int i in Integers())
{
Console.WriteLine(i.ToString());
}
}
public IEnumerable<int> Integers()
{
yield return 1;
yield return 2;
yield return 4;
yield return 8;
yield return 16;
yield return 16777216;
}
</code></pre>
<p>Lorsque vous parcourez l’exemple pas à pas, vous constaterez que le premier appel à <code>Integers()</code> retourne <code>1</code>. Le deuxième appel retourne <code>2</code> et la ligne <code>yield return 1</code> n’est plus exécutée.</p>
<p>Voici un exemple concret :</p>
<pre><code class="lang-auto">public IEnumerable<T> Read<T>(string sql, Func<IDataReader, T> make, params object[] parms)
{
using (var connection = CreateConnection())
{
using (var command = CreateCommand(CommandType.Text, sql, connection, parms))
{
command.CommandTimeout = dataBaseSettings.ReadCommandTimeout;
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
yield return make(reader);
}
}
}
}
}
</code></pre>