Implementing RAII in C#

Trent picture Trent · Apr 2, 2012 · Viewed 8.7k times · Source

I have an InfoPath form which I need to conditionally disable it's OnChange events. Since it's not possible to bind the event handlers after the form has loaded, I'm forced to rely on a global counter which indicates whether an OnChange event should be executed. Inside each OnChange event, I check whether SuppressEventsCount == 0 before performing any actions. To suppress events during the execution of some function or another, I simply set SuppressEventsCount++, and -- again when the function exits. The biggest problem with doing this is that it's not exception safe. So I had the bright idea to wrap the SuppressEvents counter in a class which implements iDisposable

using(SuppressEvents s = new SuppressEvents()){
   // OnChange events fired here are ignored
} // OnChange events enabled again

This is working, but it's still not as ideal as a c++ solution which doesn't require the use of the "using" directive at all.

Is there some way to either:

  1. Trigger a destructor or some function the moment an object goes out of scope, OR
  2. Prevent the SuppressEvents object from being initialised outside of a "using" directive entirely

Answer

Jon picture Jon · Apr 2, 2012

No and no. using is the closest you can get to RAII (more accurately, we are talking about the resource release that follows a RAII-idiom object being destructed).

To answer your points more directly:

  1. IDisposable (and by extension using) was created exactly because there is no way to do that in .NET.
  2. using is syntactic sugar that gets compiled as try/finally and only requires that the object is IDisposable, so you cannot distinguish between usage inside a using statement and out of it.