Il existe une différence significative.
L'exécution de GetByReYielding() sera exécutée différemment (car il s'agit d'un bloc d'itérateur). Si vous avez utilisé un paramètre dans GetByReturn() ou GetByReYielding() et vérifié ce paramètre à l'exécution pour la nullité (ou toute autre validation), cette vérification serait effectuée immédiatement lorsque GetByReturn() est appelée mais pas immédiatement lorsque GetByReYielding() est appelée ! La validation dans GetByReYielding() serait effectuée de manière différée, lorsque le résultat est itéré. - C'est souvent, bien, "trop tard". Voir ici:
// Checks parameters early. - Fine. The passed argument will be checked directly when
// GetByReturn() is called.
IEnumerable<int> GetByReturn(IEnumerable<int> sequence)
{
if(null == sequence)
{
throw new ArgumentNullException("sequence");
}
return GetIterator();
}
// Checks parameters in a deferred manner. - Possibly not desired, it's "too" late. I.e. // when the
// result is iterated somewhere in a completely different location in your code the
// argument passed once will be checked.
IEnumerable<int> GetByReYielding(IEnumerable<int> sequence)
{
if(null == sequence)
{
throw new ArgumentNullException("sequence");
}
for(var item in GetIterator())
{
yield return item;
}
}
M. Skeet a expliqué ce concept dans http://msmvps.com/blogs/jon_skeet/archive/2010/09/03/reimplementing-linq-to-objects-part-2-quot-where-quot.aspx. Les opérateurs de requête standard fournis dans .Net utilisent des fonctions wrapper non différées (par exemple Where()) qui vérifient les paramètres et appellent ensuite la fonction itérateur de base (comme je l'ai montré dans mon implémentation de GetByReturn()).
J'espère que cela aide.
Quel est l'avantage de donner de nouveaux rendements? Si vous voulez effectuer une action sur les éléments, vous ne serez pas en boucle, non? Si non, pourquoi ne pas utiliser la version short-code? –
Je conclus de mes expériences (et de l'inspection IL), que l'exécution de GetByReYielding() sera elle-même différée (indépendamment du fonctionnement de GetIterator()), mais pas l'exécution de GetByReturn(). C'est tout. – Nico