Resource Acquisition is Initialization in C#

Posted by codeWithoutFear on Geeks with Blogs See other posts from Geeks with Blogs or by codeWithoutFear
Published on Thu, 28 Jun 2012 11:55:52 GMT Indexed on 2012/06/28 21:17 UTC
Read the original article Hit count: 234

Filed under:

Resource Acquisition Is Initialization (RAII) is a pattern I grew to love when working in C++.  It is perfectly suited for resource management such as matching all those pesky new's and delete's.  One of my goals was to limit the explicit deallocation statements I had to write.  Often these statements became victims of run-time control flow changes (i.e. exceptions, unhappy path) or development-time code refactoring.

The beauty of RAII is realized by tying your resource creation (acquisition) to the construction (initialization) of a class instance.  Then bind the resource deallocation to the destruction of that instance.  That is well and good in a language with strong destructor semantics like C++, but languages like C# that run on garbage-collecting runtimes don't provide the same instance lifetime guarantees.

Here is a class and sample that combines a few features of C# to provide an RAII-like solution:

using System;

namespace RAII
{
    public class DisposableDelegate : IDisposable
    {
        private Action dispose;

        public DisposableDelegate(Action dispose)
        {
            if (dispose == null)
            {
                throw new ArgumentNullException("dispose");
            }

            this.dispose = dispose;
        }

        public void Dispose()
        {
            if (this.dispose != null)
            {
                Action d = this.dispose;
                this.dispose = null;
                d();
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.Out.WriteLine("Some resource allocated here.");

            using (new DisposableDelegate(() => Console.Out.WriteLine("Resource deallocated here.")))
            {
                Console.Out.WriteLine("Resource used here.");

                throw new InvalidOperationException("Test for resource leaks.");
            }
        }
    }
}

The output of this program is:

Some resource allocated here.
Resource used here.

Unhandled Exception: System.InvalidOperationException: Test for resource leaks.
   at RAII.Program.Main(String[] args) in c:\Dev\RAII\RAII\Program.cs:line 40
Resource deallocated here.

Code without fear!

--Don

© Geeks with Blogs or respective owner