Is it abusive to use IDisposable and "using" as a means for getting "scoped behavior" for exception safety?

c#, exception, raii

Solution

I don't think so, necessarily. IDisposable technically is meant to be used for things that have non-managed resources, but then the using directive is just a neat way of implementing a common pattern of `try .. finally { dispose }`.

A purist would argue 'yes - it's abusive', and in the purist sense it is; but most of us do not code from a purist perspective, but from a semi-artistic one. Using the 'using' construct in this way is quite artistic indeed, in my opinion.

You should probably stick another interface on top of IDisposable to push it a bit further away, explaining to other developers why that interface implies IDisposable.

There are lots of other alternatives to doing this but, ultimately, I can't think of any that will be as neat as this, so go for it!

Problem

Something I often used back in C++ was letting a class `A` handle a state entry and exit condition for another class `B`, via the `A` constructor and destructor, to make sure that if something in that scope threw an exception, then B would have a known state when the scope was exited. This isn't pure RAII as far as the acronym goes, but it's an established pattern nevertheless. In C#, I often want to do ``` class FrobbleManager { ... private void FiddleTheFrobble() { this.Frobble.Unlock(); Foo(); // Can throw this.Frobble.Fiddle(); // Can throw Bar(); // Can throw this.Frobble.Lock(); } } ``` Which needs to be done like this ``` private void FiddleTheFrobble() { this.Frobble.Unlock(); try { Foo(); // Can throw this.Frobble.Fiddle(); // Can throw Bar(); // Can throw } finally { this.Frobble.Lock(); } } ``` if I want to guarantee the `Frobble` state when `FiddleTheFrobble` returns. The code would be nicer with ``` private void FiddleTheFrobble() { using (var janitor = new FrobbleJanitor(this.Frobble)) { Foo(); // Can throw this.Frobble.Fiddle(); // Can throw Bar(); // Can throw } } ``` where `FrobbleJanitor` looks roughly like ``` class FrobbleJanitor : IDisposable { private Frobble frobble; public FrobbleJanitor(Frobble frobble) { this.frobble = frobble; this.frobble.Unlock(); } public void Dispose() { this.frobble.Lock(); } } ``` And that's how I want to do it. Now reality catches up, since what I want to use requires that the `FrobbleJanitor` is used with `using`. I could consider this a code review issue, but something is nagging me. Question: Would the above be considered as abusive use of `using` and `IDisposable`?

Original source

Related problems