RAII in C#

We’ve already discussed RAII in C++, now it’s time to see how we implement the same pattern in C#. We don’t manage our memory in C#, however we still need to manage other resources, like network and database conections, files and mutexes. In C++, whenever control leaves a block, the local objects defined in that block are destroyed. In C# this is not the case because the runtime uses garbage collection to manage memory. This means that the runtime periodically looks for objects that are no long referenced and deletes those that it finds. So, unfortunately, we cannot use the same trick manage resources.

In order to guarantee that a resource is released in C# we can use a finally block like so:

// acquire a resource
try
{
   // use resource and do other stuff as well
}
finally
{
   // release resource
}

A finally block will be executed whenever control leaves the try block, either because it reaches the end of the block, it reaches a return statement of an exception is thrown.

We can also encapsulate resource management with a class like in C++. In C# we normally do this by implementing the IDisposable interface. The IDisposable interface looks like this:

interface IDisposable
{
    void Dispose();
}

We acquire the resource in the constructor and we release the resource in the Dispose method.

class ResourceHolder : IDisposable
{
   public ResourceHolder()
   {
       // acquire resource here
   }

   public void Dispose()
   {
       // release resource
   }
}

The Dispose method of our ResourceHolder must be called. It does not happen automatically like a destructor in C++. We can combine a class implementing IDisposable with the finally block like this:

var holder = ResourceHolder()
try
{
   // use resource and do other stuff as well
}
finally
{
   holder.Dispose();
}

In fact, this pattern is so useful that some syntactic sugar exists for it, the using statement.

using(var holder = ResourceHolder())
{
   // use resource and do other stuff as well
}

The above code is exactly equivalent to our previous code example with an explicit finally block. Whenever control exits the using block, the Dispose method of the object declared inside the using statement is called.

RAII is a great example of something that ends up being more complicated in C# than it is in C++. Usually, things are easier in C#!

Leave a Reply

Your email address will not be published. Required fields are marked *