When is it wise to check if this object has been deleted and throw an ObjectDisposedException?

In a class that implements IDisposable , when is it wise to check if an object has been deleted and throw an ObjectDisposedException if it is? In all public methods and properties (except Dispose )? Sometimes? Never?

+6
source share
5 answers

If an object supports IsDisposed, this method should never throw; for many other methods, it would be useful if IsDisposed returns true, but an exception should be thrown by these methods, not IsDisposed. One could use the AssertNotDisposed utility method, which would throw out if the object was deleted, but such behavior would be expected from a method with this name.

Otherwise, I would suggest that there are many cases where it is useful to have an object containing an IDisposable and be able to delete the internal object while maintaining a useful state. For example, an object whose function is to display and maintain a modeless dialog box for receiving information from the user can usefully save a copy of the contents of the fields even after closing the box. Such an object should provide a Close method that will delete internal one-time objects, but maintain a healthy state. Although it may also have a Dispose method that will call Close, but also set the “NoLongerValid” flag, which can invoke field properties, I don't think that would really add a value.

I will give that many cases in which an object may contain a useful state after its placement indicate a class that may need to be split. For example, the Font class may need to be split into the non-transitional FontInfo class (containing the font description but not the GDI descriptor) and the IDisposable ReadyFont class (inheriting the FontInfo and encapsulating the GDI font object). Font routines can check if the object to which they were provided was FontInfo or ReadyFont; in the first case, they can create a GDI font, use it and release it; in the latter case, they can use the ReadyFont GDI font object and free it. Then the creator of ReadyFont will be responsible for ensuring that it is cleaned.

Be that as it may, I don’t know if the system will try to use the GDI object associated with the Font property of the control when rendering the control, but I know that it will not show if the font is deleted (even if it was deleted before it was assigned to font property!). The controls are certainly capable of creating new GDI fonts if necessary; I don’t know if they always create a new GDI font or if they only do it if the old one has been removed. The previous behavior would seem to be more efficient, but if it had not been encoded, it could cause problems if one thread tried to remove its font while the other thread used it.

+2
source

You should implement this check only in methods that do not work with the located object.

For instance:
If your class closes database connections or file descriptors in Dispose , all methods that need these database connections or files should check to see if the instance has already been opened.

+4
source

The only thing that is really indicated is that public void Dispose() itself should not throw anything.

And any method that needs managed resources (un) should throw.

This leaves, in my opinion, only a few controversial cases:

  • IsOpen, IsDisposed: I would not choose
  • another IsSomeStatus: it depends.
  • Length, quantity, position: I don’t think the closed stream has a length, so drop it

It is harder when a class combines (unrelated) functions like Stream and Collection. We simply must not do this.

+2
source

As you say, I would perform this check in all public methods and properties except Dispose and IsDisposed. This is a standard template so that the developer does not use your type in the false impression that it is still valid.

+1
source

Using a hosted object is a programming error that you want to find as quickly as possible.

The more places you check, the faster you will find a mistake.
You should definitely check where the located object will cause some other kind of exception (i.e. the Null pointer) so as not to confuse the user.

In other places, it depends on the application if it is worth the effort.

+1
source

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


All Articles