Coverity, Enumerable.Where (this ...) and IDisposable

So, code analysis tells me that Enumarble.Where(this ...) returns an instance of WhereListIterator<T> , which (looks) like an internal type within .NET that implements IDisposable .

Stealth does not like IDisposable to go uncontrollable, and therefore offers me to get rid of the specified instance. Obviously, I cannot get rid of the instance without doing some type checking, since Enumerable.Where(this ...) is said to return an IEnumerable<T> , which does not matter from IDisposable .

My question is this: does .NET expect me to dispose of WhereListIterator<T> , or WhereListIterator<T> iterator dispose of itself (say, after each listing). If I'm not going to get rid of it, then why is the interface implemented? This leads me to a third, slightly unrelated question: if IDisposable was implemented explicitly, would Coverity (code analysis) still think that I should handle it?

Code example:

 var myList = new List<int>{ 1, 2, 3, 4 }; var evenNumbers = myList.Where(x => x % 2 == 0); foreach(var number in evenNumbers) { Console.WriteLine(number); } if(evenNumbers is IDisposable) { ((IDisposable)evenNumbers).Dispose(); // This line will be executed } 
+6
source share
2 answers

No, you do not need to get rid of it yourself. Please note that you can demonstrate such things without requiring LINQ. In this case, I believe that WhereListIterator<T> is actually a hand-written class, but the iterator block shows something like this:

 using System; using System.Collections.Generic; public class Program { static void Main(string[] args) { var empty = Empty(); Console.WriteLine(empty is IDisposable); // Prints True } static IEnumerable<string> Empty() { yield break; } } 

It really implements IDisposable because it implements not only IEnumerable<T> , but also IEnumerator<T> as an optimization - iterability acts like an iterator, in the general case when you only repeat once. The foreach will implicitly dispose of IEnumerator<T> , and you don't need to get rid of it if you don't iterate anyway.

In principle, you are beautiful here - although it is a pity that Coverity warns you about this. (I didn't use Coverity myself, to be honest, I don't know if there is anything you can do to customize its behavior here.)

+12
source

if you do not use foreach loop and use the old iteration method

 var v = new List<int>() { 1,2,3}; var enumerator = v.GetEnumerator(); while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); } 

then you must call the Dispose method

+5
source

Source: https://habr.com/ru/post/902879/


All Articles