Dispose () or Not To Dispose () elements in an array of IDisposable objects?

There are many examples of arrays or lists of IDisposable objects returned from functions in .NET. For example, Process.GetProcesses() .

  • If I call this method, is it my responsibility to Dispose () all the members of the array as I repeat them through?
  • Why this should be my responsibility, since I never created objects, and the array that gave me are just pointers to objects created outside of my code.

I always thought that this was the benefit of the creator of Dispose (). So what is the right rule here?

+6
source share
3 answers

There is no general rule. This will depend on the situation and how this method is designed, depending on whether "you" are responsible for deleting objects that you have access to. This is where documentation is often important to help users of the type understand their responsibilities.

I always thought it was the burden of the creator of Dispose()

This cannot be strictly true. Sometimes it happens that a one-time object comes out of life, creating it. Although it is simple when the creator can dispose of the object, it is sometimes simply impossible for them. When returning a disposable object from a method, there is one situation where it is often impossible for the code that creates the disposable object to clear it, since its lifetime must be less than the lifetime of a disposable object.

+7
source

With relatively few exceptions (most of which can be described as the lowest level approaches to working with poorly developed code that cannot be modified), each instance of IDisposable must at any given time have exactly one clearly defined owner. In cases where the method returns something of the type that implements IDisposable , the contract for the method indicates whether the method of ownership is freed (in this case, the caller must ensure that the object is deleted - either by deleting the object on its own or abandoning ownership of someone to another), or the method simply returns a reference to an object belonging to someone else.

In correctly written code, the question of whether an object should be placed is rarely a court decision. The owner of the object must ensure its placement; no one else should dispose of it. Sometimes it may be necessary for a method to accept a parameter indicating whether the method should transfer ownership of IDisposable . For example, if the code wants to create a sound, pass it on to the method “start playing sound” and will never want to deal with this sound again, it may be most convenient for the code to play a sound that receives reception and delete the sound when it is done; however, if the code wants to be able to play sound several times, and will ensure that the sound object remains alive until it is needed, it would be more convenient if the sound code did not become owned. Using separate methods may be cleaner in some cases, but using a parameter can help encapsulation.

As a rule, when the code returns a list of objects that implement IDisposable , the purpose of the code is to identify objects without conveying any interest to them. In the absence of ownership, the code receiving such a list should not call Dispose on it.

+1
source

The rule is very simple: if you think that other programs will use your IDisposables , then do not destroy them. Otherwise, do it.

For example: GetProcesses() returns other processes that are potentially used by other programs, so you should not host them.

On the other hand, the files you opened must be released for other processes in the OS, so you must close and place wrapper threads above them (say, you should leave the steam returned by the File.Open method).

Update :
From MSDN :

  • DO implements the Basic Dispose pattern on types containing instances of one-time types. See the Basic Dispose Pattern section for more information on the basic pattern. If the type is responsible for the life of other disposable objects, developers need a way to dispose of them too. Using Containers The Dispose method is a convenient way to make this possible.
    • DO implement a basic deletion pattern and provide a finalizer of types containing resources that must be freed explicitly and do not have finalizers.
      For example, the template should be implemented on the storage types of unmanaged memory buffers. The Finalized Types section discusses recommendations for implementing finalizers.
    • CONSIDER that implements the Basic Dispose Pattern on classes that themselves do not store unmanaged resources or disposable objects, but may have subtypes that do this.
0
source

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


All Articles