Hay una diferencia relevante.
La ejecución de GetByReYielding() se ejecutará de forma diferida (ya que es un bloque iterador). Si usó un parámetro en GetByReturn() o GetByReYielding() y verificó ese parámetro en el tiempo de ejecución en busca de nulidad (o hizo alguna otra validación), esta verificación se realizará inmediatamente cuando se invoque GetByReturn() pero no inmediatamente cuando se llame a GetByReYielding() ! La validación en GetByReYielding() se realizará de forma diferida, cuando el resultado se itera. - Esto es a menudo, bueno, "demasiado tarde". Ver aquí:
// 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;
}
}
Sr. Skeet explicó este concepto en http://msmvps.com/blogs/jon_skeet/archive/2010/09/03/reimplementing-linq-to-objects-part-2-quot-where-quot.aspx. Los operadores de consulta estándar proporcionados en .Net usan funciones de derivador no diferidas (por ejemplo, Where()) que verifican los parámetros y luego llaman a la función del iterador principal (como mostré en mi implementación de GetByReturn()).
Espero que esto ayude.
¿Cuál es la ventaja de volver a producir? Si desea realizar alguna acción en los artículos, no se moverá, ¿no? Si no, ¿por qué no utilizar la versión de código más corto? –
Concluyo de mis experimentos (y de la inspección IL), que la ejecución de GetByReYielding() se aplazará por sí misma (independientemente de la forma en que funciona GetIterator()), pero la ejecución de GetByReturn() no. Eso es todo. – Nico