c# - read - ¿Debo considerar deshacerme de cualquier IEnumerable<T> que uso?
set ienumerable c# (1)
No, no necesitas preocuparte por esto.
El hecho de que devuelvan una implementación IDisposable
es un detalle de la implementación, es porque los bloques iteradores en la implementación de Microsoft del compilador C # suceden para crear un único tipo que implementa tanto IEnumerable<T>
como IEnumerator<T>
. El último se extiende como IDisposable
, y es por eso que lo estás viendo.
Código de muestra para demostrar esto:
using System;
using System.Collections.Generic;
public class Test
{
static void Main()
{
IEnumerable<int> foo = Foo();
Console.WriteLine(foo is IDisposable); // Prints True
}
static IEnumerable<int> Foo()
{
yield break;
}
}
Tenga en cuenta que debe tener en cuenta el hecho de que IEnumerator<T>
implementa IDisposable
. Por lo tanto, cada vez que repite de forma explícita, debe deshacerse de él correctamente. Por ejemplo, si desea iterar sobre algo y asegurarse de que siempre tendrá un valor, puede usar algo como:
using (var enumerator = enumerable.GetEnumerator())
{
if (!enumerator.MoveNext())
{
throw // some kind of exception;
}
var value = enumerator.Current;
while (enumerator.MoveNext())
{
// Do something with value and enumerator.Current
}
}
(Un bucle foreach
lo hará automáticamente, por supuesto).
Se me ha señalado recientemente que varios métodos de extensión de Linq (como Where
, Select
, etc.) devuelven un IEnumerable<T>
que también es IDisposable
. Lo siguiente se evalúa como True
new int[2] {0,1}.Select(x => x*2) is IDisposable
¿Debo deshacerme de los resultados de una expresión Where
?
Cada vez que llamo a un método que devuelve IEnumerable<T>
, ¿estoy (potencialmente) aceptando la responsabilidad de llamar a disponer cuando termine con él?