Dois-je envisager de disposer de tout IEnumerable que j’utilise?

On m’a récemment signalé que diverses méthodes d’extension Linq (comme Where , Select , etc.) renvoient un IEnumerable qui se trouve également être IDisposable . La suivante évalue à True

 new int[2] {0,1}.Select(x => x*2) is IDisposable 

Dois-je disposer des résultats d’une expression Where ?

Chaque fois que j’appelle une méthode renvoyant IEnumerable , est-ce que j’accepte (potentiellement) la responsabilité d’appeler quand j’en ai fini?

    Non, vous n’avez pas à vous soucier de cela.

    Le fait qu’ils retournent une implémentation IDisposable est un détail d’implémentation, car les blocs d’iterators de l’implémentation Microsoft du compilateur C # créent un type unique qui implémente à la fois IEnumerable et IEnumerator . Ce dernier étend IDisposable , c’est pourquoi vous le voyez.

    Exemple de code pour démontrer cela:

     using System; using System.Collections.Generic; public class Test { static void Main() { IEnumerable foo = Foo(); Console.WriteLine(foo is IDisposable); // Prints True } static IEnumerable Foo() { yield break; } } 

    Notez que vous devez noter que IEnumerator implémente IDisposable . Donc, chaque fois que vous parcourez explicitement, vous devez vous en débarrasser correctement. Par exemple, si vous voulez parcourir quelque chose et être sûr que vous aurez toujours une valeur, vous pouvez utiliser quelque chose comme:

     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 } } 

    (Une boucle foreach fera automatiquement, bien sûr.)