Tengo una función que acepta un enumerable. Necesito asegurarme de que se evalúa al enumerador, pero prefiero no crear una copia (por ejemplo, a través de ToList() o ToArray()) si todo está listo en una lista o en alguna otra colección "inmovilizada". Por Frozen me refiero a colecciones donde el conjunto de elementos ya está establecido, p. List, Array, FsharpSet, Collection, etc., a diferencia de linq cosas como Select() y where().¿Es posible determinar si un IEnumerable <T> tiene ejecución diferida pendiente?
¿Es posible crear una función "ForceEvaluation" que pueda determinar si el enumerable ha diferido la ejecución pendiente, y luego evaluar el enumerable?
public void Process(IEnumerable<Foo> foos)
{
IEnumerable<Foo> evalutedFoos = ForceEvaluation(foos)
EnterLockedMode(); // all the deferred processing needs to have been done before this line.
foreach (Foo foo in foos)
{
Bar(foo);
}
}
public IEnumerable ForceEvaluation(IEnumerable<Foo> foos)
{
if(??????)
{ return foos}
else
{return foos.ToList()}
}
}
Después de algunas investigaciones más me he dado cuenta de que esto es prácticamente imposible en cualquier sentido práctico, y requeriría la inspección código complejo de cada iterador.
Así que voy a ir con una variante de la respuesta de Marcos y crear una lista blanca de tipos seguros conocidos y simplemente llamar a ToList() cualquier cosa que no esté en eso no está en la lista blanca.
Gracias a todos por su ayuda.
Editar * Después de aún más reflexión, me he dado cuenta de que esto es equivalente al problema de detención. Muy imposible.
Puede verificar 'if (foos is IList)', aunque esto probablemente sea un hack. Esto funciona incluso cuando 'foos' es una matriz. –
dasblinkenlight
¿Qué desea que suceda con 'while (true) {return return 1; } '? Sospecho que probablemente estés haciendo algo mal. Además, aquellos que están sugiriendo 'if (foos es' IList ')' no se están dando cuenta de que 'IList ' * puede * implementarse también de forma perezosa. –
jason
"Ejecución diferida" es un término tan amplio que puede significar casi cualquier cosa. ¿Está tratando de manejar un caso específico (es decir, 'IQueryable'). Si es así, compruebe el tipo 'IQueryable' y ejecute' ToList() 'contra eso). –