Disposable C# Snippets

Visual Studio code snippets were brought up a couple times today.  Which reminded me of the only two snippets I’ve ever written and used.  I think they’re useful to save me some typing.  In C# whenever you have some class that is holding onto unmanaged resources, or even a lot of managed resources, you really need to make it IDisposable.  The problem is it’s a fair amount of repetitive typing to get there. 

I have two versions: one for a base class and one for a derived class.  You use the Base Dispose Pattern snippet if your class is the first class in your hierarchy that implements IDisposable.  You use the Derived Dispose Pattern snippet if your class is derived from another class that implements IDisposable.  Just put your caret on a line within class scope, but outside method scope.  Hit the old “Ctrl K X”, select “My Code Snippets” from the context menu, then find the correct Dispose Pattern.  Don’t forget to add IDisposable to your class definition if it’s a base disposable class.

After the snippet is pasted you’ll have a couple sections to fill in.  The fill in sections are marked with comments.  The managed section is where you clean up your managed member data.  You would do this by calling Dispose() on IDisposable types and breaking references by setting them to null.  This makes it easier for the garbage collector to know what to clean up.  For example:

// if x is a disposable type:

if (x != null)

{

    x.Dispose();

    x = null;

}

 

// if x is not a disposable reference type:

x = null;

The unmanaged section is where you would clean up any native resources used by your class.  For example: you would close any open win32 handles there.

The disposed member variable can be used in debugging to find out if your object is being referenced after it’s been disposed.  This is a bad thing, but you can quickly check for it by using code like the following:

public void MyMethod()

{

    if (disposed)

    {

        throw new ObjectDisposedException(“MyClass.MyMethod() called on disposed object!”);

    }

    // TODO: write method code.

}

Copy these two files into your DocumentsVisual Studio 2008Code SnippetsVisual C#My Code Snippets folder:

Base Dispose Pattern.snippet:

<?xml version=1.0 encoding=utf-8?>

<CodeSnippets xmlns=http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet>

  <CodeSnippet Format=1.0.0>

    <Header>

      <Title>

        Base Dispose Pattern

      </Title>

    </Header>

    <Snippet>

      <Declarations>

        <Literal Editable=false>

          <ID>classname</ID>

          <ToolTip>The name of this class.</ToolTip>

          <Default>BaseResource</Default>

          <Function>ClassName()</Function>

        </Literal>

      </Declarations>

      <Code Language=CSharp>

        <![CDATA[private bool disposed = false;

 

        public void Dispose()

        {

            Dispose(true);

            GC.SuppressFinalize(this);

        }

 

        protected virtual void Dispose(bool disposing)

        {

            if (!disposed)

            {

                if (disposing) // Managed:

                {

                }

                // Unmanaged:

            }

            disposed = true;

        }

 

        ~$classname$()

        {

            Dispose(false);

        }]]>

      </Code>

    </Snippet>

  </CodeSnippet>

</CodeSnippets>

Derived Dispose Pattern.snippet:

<?xml version=1.0 encoding=utf-8?>

<CodeSnippets xmlns=http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet>

  <CodeSnippet Format=1.0.0>

    <Header>

      <Title>

        Derived Dispose Pattern

      </Title>

    </Header>

    <Snippet>

      <Code Language=CSharp>

        <![CDATA[private bool disposed = false;

 

        protected override void Dispose(bool disposing)

        {

            if (!disposed)

            {

                try

                {

                    if (disposing) // Managed:

                    {

                    }

                    // Unmanaged:

                    disposed = true;

                }

                finally

                {

                    base.Dispose(disposing);

                }

            }

        }]]>

      </Code>

    </Snippet>

  </CodeSnippet>

</CodeSnippets>

Enjoy!

8 Responses to “Disposable C# Snippets”

  1. Krista Says:

    Not only will Visual Studio snippets save you time but the Code Metrics will save you money. Microsoft rocks, is there anyone else even out there?

  2. hempelcx Says:

    One small note.

    You suggested “breaking references by setting them to null” in the Dispose method. While there is no harm in doing that, there’s usually no value in doing it either. It’s a common thing to see from VB and Delphi developers, especially, but it’s really unnecessary in .NET.

    When the GC runs, it builds a graph starting with all root object references and chases each reference outward from there. So if your object has already been explicitly disposed at the time the GC runs, odds are there are no root references to it anyway (it is no longer, “rooted”.) On the other hand, if Dispose is being called during finalization – well that also means there are no longer any strong references to it.

    One exception that comes to mind is with multi-threaded applications. This has nothing to do with garbage collection, but rather state management. In short, in a multi-threaded process it is entirely possible that your object is being disposed on one thread at the same time members of the object are being referenced in another thread. There are ways to prevent that via critical sections within the Dispose method, but you need to be careful not to deadlock the Finalizer! So another option is to set each variable to null in the Dispose method which effectively prevents them from being accessed by other threads. Odds are, though, that’s just going to result in a bunch of unpredictable NullReferenceExceptions… :)

    The one other scenario I can think of would be if your object was being retained via a “weak reference” and there was a chance it may be resurrected after being disposed. It’s messy business – but in that one case, there could be some benefit to setting internal references to null in the Dispose method (benefits which are, again, more related to state management than garbage collection.)

    At any rate – like I sad, there’s no harm in setting those variables to null. There’s just also (usually) no benefit.

  3. cgassib Says:

    Those are some good points. In a perfect world, you shouldn’t have to set things to null in a managed environment, but I have been personally burned by the multithreaded case you mentioned. I just find it saves me debugging time and hassle in the future if I’m thorough up front. When I suspect some disposed object is being called after death I start to add checks in my code for the value of the “disposed” member that the snippet creates.

    I have a theory about the GC. I don’t have the .NET GC code in front of me to back this up; but I’ve written some graph algorithms before, and I know the algorithms to check for cycles are not super fast to compute. If you break the cycles you know about for the GC, you could potentially be saving the GC a lot of work there. Speeding up the GC’s work should result in speeding up your whole application. Like I said, I haven’t performance tested this myself, but it would surprise me a little to find out otherwise.

    The other time not setting references to null has burned me: is when a large amount of data is no longer needed, but a single reference to that data is still held quietly by some object I’m still using. Because none of their references have been broken, the garbage collector will keep the entire pool of objects around because of one event subscription for example. It’s really easy to “leak” in .NET this way. You think you’ve gotten rid of some data, but some object didn’t unsubscribe from an event or otherwise break its references.

  4. fsoldt Says:

    Great snippet. Is it possible to use this in VS 2005? I haven’t been able to get this to work.
    Frits

  5. cgassib Says:

    Yes, it does work in VS 2005. Copy the two files to your “[Documents]\Visual Studio 2005\Code Snippets\Visual C#\My Code Snippets” folder. The files should be named: “Base Dispose Pattern.snippet” and “Derived Dispose Pattern.snippet”.

  6. fsoldt Says:

    I did that, but then, when I use the code snippet manager to import the files, I get the error “The snippet files chosen were not valid”. I checked the code but is seems OK.
    Any suggestions? Thanks.

  7. cgassib Says:

    Looks like my web formatting tool replaces all double-quote characters with something else. Replace whatever double-quote character in my examples with ASCII-34 and it should import fine.

  8. fsoldt Says:

    Thanks, that did the trick. I had to replace all the “spaces” too, don’t know which character it was. It looked like a space but wasn’t.

Leave a Reply