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#!

The Tricky Little Differences Between C# and C++ – part 1

There are a lot of big differences between C++ and C#. Really, despite their similar syntax, they are completely different languages. C# has garbage collection, C++ has manual memory management. C# is compiled to a special intermediate language that is then just in time compiled by the run time. C++ is compiled to machine code.

But, when you transfer between the two languages you are probably not going to get caught out by obvious things like that. It’s much more likely that the small subtle differences will trip you up. I’m going to cover some of these little differences that I’ve come across.

In this post we’ll be looking at uninitialised strings. Suppose we create a string in C++ without instantiating it directly ourselves and then print its contents. Like this:

string s;
cout << s << endl; 

This will just print an empty line, because the string s is empty. However, if you try the same thing in C#, it won’t work quite the same. If we use C# and do something like:

string s;
Console.WriteLine(s);

we’ll get the following runtime error:

Program.cs(10,31): error CS0165: Use of unassigned local variable 's'

This is a little surprising, normally C# is the more user friendly language. But in this case in C++ we get a friendly default behaviour whereas in C# we get a nasty runtime exception. Why?

This is because, in our C++ example we created a string object on the stack and dealt with it directly. When we created it, C++ called the default constructor which creates an empty string. However, in C# strings are reference types. This means that whenever we create one we are creating an object on the (managed) head. So our C# is really equivalent to the following C++ code:

String* s = NULL;
count << *s << endl;

If you run this you’ll end up with a seg fault, that’s because a null pointer points to memory address 0 which is inaccessible to you.