Using ObjectDisposedException

When implementing the Dispose pattern, object properties must raise an ObjectDisposedException after the object has been deleted.

It seems like a lot of repeating code if each property and method has a line of code at the start of the setter and getter to throw this exception, even if it's just ThrowIfDisposed (). If you have 40 properties, then 80 duplicate rows. In a large class, it can add up very quickly.

I could not find a better way, so it seems that it is, but I thought I would ask. Is there a better way?

+5
source share
2 answers

If you have 40 properties in one class, you probably have a design problem, but the transition ... It really depends on the specific use case, but you should just throw an ObjectDisposedException if the property cannot actually be resolved, because the class has been deleted. To give a concrete example:

public class MyStream : IDisposable { private string name; private Stream stream; public MyStream(string name) { this.Name = name; this.Stream = new FileStream(...); } public string Name { get { return this.name; } } public Stream Stream { get { if (this.IsDisposed) { throw new ObjectDisposedException(); } return this.stream; } } private bool IsDisposed { get; set; } public void Dispose() { if (!this.IsDisposed) { this.IsDisposed = true; this.Stream.Dispose(); this.Stream = null; } } } 

Here, the Stream property throws an exception because the main stream has been deleted, so it can no longer be used. But Name has no reason to quit. From there, in many cases, you can decompose your code so that access to the actual problematic property throws an exception:

 public int Length { get { // Since we access the Stream property, the ObjectDisposedException // will be thrown when the class is disposed return this.Stream.Length; } } 

If you still have too many properties to decorate even after this template, you can use libraries like Fody , which allows you to enter compile-time behavior. Using it, you can make the [ThrowIfDisposed] attribute, which you apply to the properties as needed.

+7
source

Check another topic: Handle ObjectDisposedException correctly in the IDisposable class hierarchy

You do not need to throw an exception every time someone accesses a property of a class that implements :IDisposable . This is only necessary if you are accessing an object that should be deleted (for example, write / read files, access network sockets ...). For all other cases, you can just go with the idea of ​​a normal class.

Usually, objects / classes do not have such a large number of properties, since it is possible to divide them into several classes → that will allow you to do only part of this :IDisposable , and the rest will be independent of the IDisposable class.

0
source

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


All Articles