Skip to main content

Blue Man Holding a Pencil and Drawing a Circle on a Blueprint Clipart Illustration I’ve been working on an interesting project recently and found that I needed two pieces of code a lot, so what better than wrapping them as snippets.

What are snippets?

Well if you start typing in VS you may see some options with a torn paper icon, if you select that and hit tab (or hit tab twice, once to select and once to invoke) it will write code for you! These are contained in .snippet files, which are just XML files in a specific location.

image 

To deploy these snippets copy them to your C# custom snippet’s folder which should be something like C:\Users\<Username>\Documents\Visual Studio 2008\Code Snippets\Visual C#\My Code Snippets

You can look at the end of this post for a sample of what the snippets create, but lets have a quick overview of them.

Snippet 1: StructC

Visual Studio already includes a snippet for creating a struct (which is also the snippet) however it is very bland:

image

StructC is a more complete implementation of a struct, mainly so it complies with fxCop requirements for a struct. So it includes:

  • GetHashCode method
  • Both Equals methods
  • The positive and negative equality operators (== and !=)
  • Lots of comments

which all in all runs in at 74 lines of code, rather than the three you got previously.

Warning - the GetHashCode uses reflection to figure out a unique hash code, but this may not be best for all scenarios. Please review prior to use.

Snippet 2: Dispose

If you are implementing a class that needs to inherit IDisposable you can use the the option in VS to implement the methods.

image

Once again from a fxCop point of view it is lacking since you just get the Dispose method. Now instead of doing that you can use the dispose snippet which produces 41 lines of code which has:

  • Region for the code - same as if you used the VS option
  • Properly implemented Dispose method which calls Dispose(bool) and GC.SuppressFinalize
  • A Dispose(bool) method for cleanup of managed and unmanaged objects
  • A private bool variable to make sure we do not call dispose multiple times.

StructC Sample

/// <summary></summary>
struct MyStruct
{
    //TODO: Add properties, fields, constructors etc...

    /// <summary>
    /// Returns a hash code for this instance.
    /// </summary>
    /// <returns>
    /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
    /// </returns>
    public override int GetHashCode()
    {
        int valueStorage = 0;
        object objectValue = null;
        foreach (PropertyInfo property in typeof(MyStruct).GetProperties())
        {
            objectValue = property.GetValue(this, null);
            if (objectValue != null)
            {
                valueStorage += objectValue.GetHashCode();
            }
        }

        return valueStorage;
    }

    /// <summary>
    /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
    /// </summary>
    /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
    /// <returns>
    ///     <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
    /// </returns>
    public override bool Equals(object obj)
    {
        if (!(obj is MyStruct))
            return false;

        return Equals((MyStruct)obj);
    }

    /// <summary>
    /// Equalses the specified other.
    /// </summary>
    /// <param name="other">The other.</param>
    /// <returns></returns>
    public bool Equals(MyStruct other)
    {
        //TODO: Implement check to compare two instances of MyStruct
        
        return true;
    }

    /// <summary>
    /// Implements the operator ==.
    /// </summary>
    /// <param name="first">The first.</param>
    /// <param name="second">The second.</param>
    /// <returns>The result of the operator.</returns>
    public static bool operator ==(MyStruct first, MyStruct second)
    {
        return first.Equals(second);
    }

    /// <summary>
    /// Implements the operator !=.
    /// </summary>
    /// <param name="first">The first.</param>
    /// <param name="second">The second.</param>
    /// <returns>The result of the operator.</returns>
    public static bool operator !=(MyStruct first, MyStruct second)
    {
        return !first.Equals(second);
    }
}                

Dispose Sample

#region IDisposable Members

/// <summary>
/// Internal variable which checks if Dispose has already been called
/// </summary>
private Boolean disposed;

/// <summary>
/// Releases unmanaged and - optionally - managed resources
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
private void Dispose(Boolean disposing)
{
    if (disposed)
    {
        return;
    }

    if (disposing)
    {
        //TODO: Managed cleanup code here, while managed refs still valid
    }
    //TODO: Unmanaged cleanup code here

    disposed = true;
}

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
    // Call the private Dispose(bool) helper and indicate 
    // that we are explicitly disposing
    this.Dispose(true);

    // Tell the garbage collector that the object doesn't require any
    // cleanup when collected since Dispose was called explicitly.
    GC.SuppressFinalize(this);
}

#endregion