WeakReferenceDictionary

Further to the last post on my implementation of a strongly-typed variant of WeakReferemce, I thought it would be apropos to post another utility class surrounding weak references. This one really is more academic than useful considering that one could just stick WeakReference<T> into a regular Dictionary<TKey, TValue> and get almost the same functionality. All this class really does is hide away how we're managing the reference inside the dictionary.

/// <summary>
/// Represents a dictionary that only holds weak references on values stored within it.
/// </summary>
/// <typeparam name="TKey">The type of the key.</typeparam>
/// <typeparam name="TValue">The type of the value.
/// <remarks>This must be a reference type (by definition, there's no reason to have a weak reference on value types).</remarks>
/// </typeparam>
public class WeakReferenceDictionary<TKey, TValue> : IDictionary<TKey, TValue> where TValue : class
{
    private readonly Dictionary<TKey, WeakReference<TValue>> realDictionary;

    /// <summary>
    /// Initializes a new instance of the <see cref="WeakReferenceDictionary"/>
    /// class that is empty, has the default initial capacity, and uses the default
    /// equality comparer for the key type.
    /// </summary>
    public WeakReferenceDictionary()
    {
        this.realDictionary = new Dictionary<TKey, WeakReference<TValue>>();
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="WeakReferenceDictionary"/>
    /// class that is empty, has the specified initial capacity, and uses the default
    /// equality comparer for the key type.
    /// </summary>
    /// <param name="capacity">
    /// The initial number of elements that the <see cref="WeakReferenceDictionar"/>
    /// can contain.
    /// </param>
    /// <exception cref="System.ArgumentOutOfRangeException">
    /// <paramref name="capacity"/> is less than <c>0</c>.
    /// </exception>
    public WeakReferenceDictionary(int capacity)
    {
        this.realDictionary = new Dictionary<TKey, WeakReference<TValue>>(capacity);
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="WeakReferenceDictionary"/>
    /// class that is empty, has the default initial capacity, and uses the specified
    /// <see cref="System.Collections.Generic.IEqualityComparer" />.
    /// </summary>
    /// <param name="comparer">
    /// The <see cref="System.Collections.Generic.IEqualityComparer" /> implementation to use
    /// when comparing keys, or <c>null</c> to use the default <see cref="System.Collections.Generic.EqualityComparer" />
    /// for the type of the key.
    /// </param>
    public WeakReferenceDictionary(IEqualityComparer<TKey> comparer)
    {
        this.realDictionary = new Dictionary<TKey, WeakReference<TValue>>(comparer);
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="WeakReferenceDictionary" />
    /// class that is empty, has the specified initial capacity, and uses the specified
    /// <see cref="System.Collections.Generic.IEqualityComparer" />.
    /// <param name="capacity">
    /// The initial number of elements that the <see cref="WeakReferenceDictionary" />
    /// can contain.
    /// </param>
    /// <param name="comparer">
    /// The <see cref="System.Collections.Generic.IEqualityComparer<T>" /> implementation to use
    /// when comparing keys, or <c>null</c> to use the default <see cref="System.Collections.Generic.EqualityComparer<T>" />
    /// for the type of the key.
    /// </param>
    /// <exception cref="System.ArgumentOutOfRangeException">
    /// <paramref name="capacity"/> is less than <c>0</c>.
    /// </exception>
    public WeakReferenceDictionary(int capacity, IEqualityComparer<TKey> comparer)
    {
        this.realDictionary = new Dictionary<TKey, WeakReference<TValue>>(capacity, comparer);
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="WeakReferenceDictionary<TKey, TValue>"/>
    /// class that contains elements copied from the specified <see cref="System.Collections.Generic.IDictionary<TKey,TValue>" />
    /// and uses the default equality comparer for the key type.
    /// </summary>
    /// <param name="dictionary">The <see cref="System.Collections.Generic.IDictionary<TKey,TValue>" /> whose elements are
    /// copied to the new <see cref="WeakReferenceDictionary<TKey, TValue>"/>.
    /// </param>
    /// <exception cref="T:System.ArgumentNullException">
    /// <paramref name="dictionary"/> is <c>null</c>.
    /// </exception>
    /// <exception cref="T:System.ArgumentException">
    /// <paramref name="dictionary"/> contains one or more duplicate keys.
    /// </exception>
    public WeakReferenceDictionary(IDictionary<TKey, TValue> dictionary)
    {
        this.realDictionary = new Dictionary<TKey, WeakReference<TValue>>(
            dictionary.ToDictionary(pair => pair.Key, pair => new WeakReference<TValue>(pair.Value)));
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="WeakReferenceDictionary<TKey, TValue>"/>
    /// class that contains elements copied from the specified <see cref="System.Collections.Generic.IDictionary<TKey,TValue>" />
    /// and uses the specified <see cref="System.Collections.Generic.IEqualityComparer<T>" />.
    /// </summary>
    /// <param name="comparer">
    /// The <see cref="System.Collections.Generic.IDictionary<TKey,TValue>" /> whose elements are
    /// copied to the new <see cref="WeakReferenceDictionary<TKey, TValue>"/>.
    /// </param>
    /// <param name="dictionary">
    /// The <see cref="System.Collections.Generic.IEqualityComparer<T>" /> implementation to use
    /// when comparing keys, or <c>null</c> to use the default <see cref="System.Collections.Generic.EqualityComparer<T>" />
    /// for the type of the key.
    /// </param>
    /// <exception cref="System.ArgumentNullException">
    /// <paramref name="dictionary"/> is <c>null</c>.
    /// </exception>
    /// <exception cref="System.ArgumentException">
    /// <paramref name="dictionary"/> contains one or more duplicate keys.
    /// </exception>
    public WeakReferenceDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
    {
        this.realDictionary = new Dictionary<TKey, WeakReference<TValue>>(
            dictionary.ToDictionary(pair => pair.Key, pair => new WeakReference<TValue>(pair.Value)),
            comparer);
    }

    #region IDictionary<TKey,TValue> Members

    /// <summary>
    /// Adds an element with the provided key and value to the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
    /// </summary>
    /// <param name="key">The object to use as the key of the element to add.</param>
    /// <param name="value">The object to use as the value of the element to add.</param>
    /// <exception cref="T:System.ArgumentNullException">
    /// <paramref name="key"/> is null.
    /// </exception>
    /// <exception cref="T:System.ArgumentException">
    /// An element with the same key already exists in the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
    /// </exception>
    /// <exception cref="T:System.NotSupportedException">
    /// The <see cref="T:System.Collections.Generic.IDictionary`2"/> is read-only.
    /// </exception>
    public void Add(TKey key, TValue value)
    {
        this.realDictionary.Add(key, new WeakReference<TValue>(value));
    }

    /// <summary>
    /// Determines whether the <see cref="T:System.Collections.Generic.IDictionary`2"/> contains an element with the specified key.
    /// </summary>
    /// <param name="key">The key to locate in the <see cref="T:System.Collections.Generic.IDictionary`2"/>.</param>
    /// <returns>
    /// true if the <see cref="T:System.Collections.Generic.IDictionary`2"/> contains an element with the key; otherwise, false.
    /// </returns>
    /// <exception cref="T:System.ArgumentNullException">
    /// <paramref name="key"/> is null.
    /// </exception>
    public bool ContainsKey(TKey key)
    {
        return this.realDictionary.ContainsKey(key);
    }

    /// <summary>
    /// Gets an <see cref="T:System.Collections.Generic.ICollection`1"/> containing the keys of the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
    /// </summary>
    /// <value></value>
    /// <returns>
    /// An <see cref="T:System.Collections.Generic.ICollection`1"/> containing the keys of the object that implements <see cref="T:System.Collections.Generic.IDictionary`2"/>.
    /// </returns>
    public ICollection<TKey> Keys
    {
        get
        {
            return this.realDictionary.Keys;
        }
    }

    /// <summary>
    /// Removes the element with the specified key from the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
    /// </summary>
    /// <param name="key">The key of the element to remove.</param>
    /// <returns>
    /// true if the element is successfully removed; otherwise, false.  This method also returns false if <paramref name="key"/> was not found in the original <see cref="T:System.Collections.Generic.IDictionary`2"/>.
    /// </returns>
    /// <exception cref="T:System.ArgumentNullException">
    /// <paramref name="key"/> is null.
    /// </exception>
    /// <exception cref="T:System.NotSupportedException">
    /// The <see cref="T:System.Collections.Generic.IDictionary`2"/> is read-only.
    /// </exception>
    public bool Remove(TKey key)
    {
        return this.realDictionary.Remove(key);
    }

    /// <summary>
    /// Gets the value associated with the specified key.
    /// </summary>
    /// <param name="key">The key whose value to get.</param>
    /// <param name="value">When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the type of the <paramref name="value"/> parameter. This parameter is passed uninitialized.</param>
    /// <returns>
    /// true if the object that implements <see cref="T:System.Collections.Generic.IDictionary`2"/> contains an element with the specified key; otherwise, false.
    /// </returns>
    /// <exception cref="T:System.ArgumentNullException">
    /// <paramref name="key"/> is null.
    /// </exception>
    public bool TryGetValue(TKey key, out TValue value)
    {
        WeakReference<TValue> reference;
        if (this.realDictionary.TryGetValue(key, out reference))
        {
            value = reference.Target;
            return true;
        }
        else
        {
            value = default(TValue);
            return false;
        }
    }

    /// <summary>
    /// Gets an <see cref="T:System.Collections.Generic.ICollection`1"/> containing the values in the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
    /// </summary>
    /// <value></value>
    /// <returns>
    /// An <see cref="T:System.Collections.Generic.ICollection`1"/> containing the values in the object that implements <see cref="T:System.Collections.Generic.IDictionary`2"/>.
    /// </returns>
    public ICollection<TValue> Values
    {
        get
        {
            return this.realDictionary
                .Values
                .Select(value => value.Target)
                .ToList()
                .AsReadOnly();
        }
    }

    /// <summary>
    /// Gets or sets the value associated with the specified key.
    /// </summary>
    /// <param name="key">The key of the value to get or set.</param>
    /// <returns>The value associated with the specified key. If the specified key is not
    /// found, a get operation throws a <see cref="System.Collections.Generic.KeyNotFoundException"/>,
    /// and a set operation creates a new element with the specified key.</returns>
    /// <exception cref="System.ArgumentNullException">
    /// <paramref name="key"/> is <c>null</c>.
    /// </exception>
    /// <exception cref="System.Collections.Generic.KeyNotFoundException">
    /// The property is retrieved and the key does not exist in the collection.
    /// </exception>
    public TValue this[TKey key]
    {
        get
        {
            return this.realDictionary[key].Target;
        }
        set
        {
            this.realDictionary[key] = new WeakReference<TValue>(value);
        }
    }

    #endregion

    #region ICollection<KeyValuePair<TKey,TValue>> Members

    /// <summary>
    /// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1"/>.
    /// </summary>
    /// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
    /// <exception cref="T:System.NotSupportedException">
    /// The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.
    /// </exception>
    void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
    {
        Add(item.Key, item.Value);
    }

    /// <summary>
    /// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
    /// </summary>
    /// <exception cref="T:System.NotSupportedException">
    /// The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.
    /// </exception>
    public void Clear()
    {
        this.realDictionary.Clear();
    }

    /// <summary>
    /// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1"/> contains a specific value.
    /// </summary>
    /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
    /// <returns>
    /// true if <paramref name="item"/> is found in the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false.
    /// </returns>
    bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
    {
        return this.realDictionary.ContainsKey(item.Key);
    }

    /// <summary>
    /// Copies the elements of the <see cref="T:System.Collections.Generic.ICollection`1"/> to an <see cref="T:System.Array"/>, starting at a particular <see cref="T:System.Array"/> index.
    /// </summary>
    /// <param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:System.Collections.Generic.ICollection`1"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
    /// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
    /// <exception cref="T:System.ArgumentNullException">
    /// 	<paramref name="array"/> is null.
    /// </exception>
    /// <exception cref="T:System.ArgumentOutOfRangeException">
    /// 	<paramref name="arrayIndex"/> is less than 0.
    /// </exception>
    /// <exception cref="T:System.ArgumentException">
    /// 	<paramref name="array"/> is multidimensional.
    /// -or-
    /// <paramref name="arrayIndex"/> is equal to or greater than the length of <paramref name="array"/>.
    /// -or-
    /// The number of elements in the source <see cref="T:System.Collections.Generic.ICollection`1"/> is greater than the available space from <paramref name="arrayIndex"/> to the end of the destination <paramref name="array"/>.
    /// -or-
    /// Type <paramref name="T"/> cannot be cast automatically to the type of the destination <paramref name="array"/>.
    /// </exception>
    void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
    {
        if (array == null)
        {
            throw new ArgumentNullException("array", "Array cannot be null");
        }

        if ( (arrayIndex < 0) || (arrayIndex > array.Length) )
        {
            throw new ArgumentOutOfRangeException("array", "Index must be a non-negative value within the array");
        }

        if ((array.Length - arrayIndex) < this.realDictionary.Count)
        {
            throw new ArgumentException("Array is too small", "array");
        }

        foreach (var pair in this.realDictionary)
        {
            array[arrayIndex++] = new KeyValuePair<TKey, TValue>(pair.Key, pair.Value.Target);
        }
    }

    /// <summary>
    /// Gets the number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
    /// </summary>
    /// <value></value>
    /// <returns>
    /// The number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
    /// </returns>
    public int Count
    {
        get
        {
            return this.realDictionary.Count;
        }
    }

    /// <summary>
    /// Gets a value indicating whether the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.
    /// </summary>
    /// <value></value>
    /// <returns>true if the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only; otherwise, false.
    /// </returns>
    public bool IsReadOnly
    {
        get
        {
            return false;
        }
    }

    /// <summary>
    /// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
    /// </summary>
    /// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
    /// <returns>
    /// true if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>.
    /// </returns>
    /// <exception cref="T:System.NotSupportedException">
    /// The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.
    /// </exception>
    bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
    {
        return Remove(item.Key);
    }

    #endregion

    #region IEnumerable<KeyValuePair<TKey,TValue>> Members

    /// <summary>
    /// Returns an enumerator that iterates through the collection.
    /// </summary>
    /// <returns>
    /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
    /// </returns>
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        foreach (var pair in this.realDictionary)
        {
            yield return new KeyValuePair<TKey, TValue>(pair.Key, pair.Value.Target);
        }
    }

    #endregion

    #region IEnumerable Members

    /// <summary>
    /// Returns an enumerator that iterates through a collection.
    /// </summary>
    /// <returns>
    /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
    /// </returns>
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    #endregion
}

So there you have it, WeakReferenceDictionary<TKey, TValue>. It's not a complete replacement for a regular dictionary as it doesn't support all the same interfaces such as the ICollection or ISerialization. Also, I haven't fully commented everything as well as perhaps it should be. I'll leave all that as an exercise for you.

Strongly-typed WeakReference

I was playing around with weak references recently and wanted to tidy up my code a little – there were casts everywhere – so I knocked up a derivation using generics. I'm sure someone somewhere already did this, but I thought I'd share it anyway, so here it is.

/// <summary>
/// Strongly-typed weak reference.
/// </summary>
/// <typeparam name="T">The type of object being referenced.</typeparam>
public class WeakReference<T> : WeakReference, ISerializable where T : class
{
    /// <summary>
    /// Initializes a new instance of the  <see cref="WeakReference<T>"/> class, referencing
    /// the specified object.
    /// </summary>
    /// <param name="target">An object to track.</param>
    public WeakReference(T target)
        : base(target)
    {

    }

    /// <summary>
    /// Initializes a new instance of the  <see cref="WeakReference<T>"/> class, referencing
    /// the specified object and using the specified resurrection tracking.
    /// </summary>
    /// <param name="target">An object to track.</param>
    /// <param name="trackResurrection">Indicates when to stop tracking the object. If <c>true</c>, the object is tracked
    /// after finalization; if <c>false</c>, the object is only tracked until finalization..</param>
    public WeakReference(T target, bool trackResurrection)
        : base(target, trackResurrection)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="WeakReference<T>"/> class.
    /// </summary>
    /// <param name="info">An object that holds all the data needed to serialize or deserialize the current <see cref="T:System.WeakReference"/> object.</param>
    /// <param name="context">(Reserved) Describes the source and destination of the serialized stream specified by <paramref name="info"/>.</param>
    /// <exception cref="T:System.ArgumentNullException">
    /// 	<paramref name="info"/> is null. </exception>
    protected WeakReference(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
    }

    /// <summary>
    /// Gets or sets the object (the target) referenced by the current <see cref="T:System.WeakReference"/> object.
    /// </summary>
    /// <value></value>
    /// <returns>null if the object referenced by the current <see cref="T:System.WeakReference"/> object has been garbage collected; otherwise, a reference to the object referenced by the current <see cref="T:System.WeakReference"/> object.</returns>
    /// <exception cref="T:System.InvalidOperationException">The reference to the target object is invalid. This exception can be thrown while setting this property if the value is a null reference or if the object has been finalized during the set operation.</exception>
    public new T Target
    {
        get
        {
            return (T)base.Target;
        }

        set
        {
            base.Target = value;
        }
    }
}

There's not much to say about this class. I've replaced the Target property of the original WeakReference class with a strongly-typed one based on the type parameter, T. The other bits are just constructors to mirror those in the base class and it's job done.

Deserializing from a sequence of bytes

I was working on some file-based persistence today and found myself needing to load a string from an array of bytes that represented that string's characters. There is, of course, more than one way to skin this particular cat, but I took it as an opportunity to play around with extension methods.

The first way I found to do this was to have a method with an iterator block that took each pair of bytes and used the BitConverter.ToChar() method to yield a character.

public static IEnumerable<char> ToChars(this IEnumerable<byte> sequence)
{
    int counter = 0;
    byte[] bytes = new byte[2];

    foreach (var b in sequence)
    {
        bytes[counter++ % 2] = b;
        if (counter % 2 == 0)
        {
            yield return BitConverter.ToChar(bytes, 0);
        }
    }
}

Turning the results of this method into an array and using the appropriate string constructor meant job done. I realise that a little more work is needed to check we have a non-null sequence with an even number of bytes, but this is just illustrative. However, what if I had wanted a sequence of integers or doubles or some other type?

A more elegant solution would be to create a partitioning method that took the sequence of bytes and returned a sequence of smaller sequences.

public static IEnumerable<byte[]> Partition(this IEnumerable<byte> sequence, int partitionSize)
{
    bool any = false;

    int partitionIndex = 0;
    byte[] partition = new byte[partitionSize];
    foreach (var b in sequence)
    {
        any = true;
        partition[partitionIndex++] = b;

        if (partitionIndex >= partitionSize)
        {
            yield return partition;
            partitionIndex = 0;
        }
    }

    // We have a partial partition to yield.
    if (any && (partitionIndex != 0))
    {
        yield return partition;
    }
}

This time, we've got ourselves a sequence of byte arrays. To get the characters we would've got from the previous example, we have to perform a quick Select() call on the sequence.

var sequenceOfChar = sequenceOfBytes
    .Partition(sizeof(char))
    .Select(x => BitConverter.ToChar(x, 0));

Of course, if we wanted a sequence of integers, the call would be a little different.

var sequenceOfInt32 = sequenceOfBytes
    .Partition(sizeof(int))
    .Select(x => BitConverter.ToInt32(x, 0));

There's a little more polish required to cope with null sequences and there's no guarantee that the last array in the partitioned sequence will have enough bytes for a full partition. Finally, in my examples this relies on the data being persisted in the order expected by the BitConverter calls, but you could manage that yourself depending on your own circumstances.

Is this useful to anyone else? Is there a better way to achieve the same goals?

St. Patrick's Day

static class Program
{
    public static void Main()
    {
        EnjoyStPatricksDay.WithAGuinness();
    }
}

static class EnjoyStPatricksDay
{
    public static readonly Person Me = People.Jeff;
    public static readonly City CurrentCity = Cities.Chicago;

    public static void WithAGuiness()
    {
        if (CurrentCity.HasGuinness)
        {
            EnjoyStPatricksDay.WithAGuinness();
        }
        else
        {
            EnjoyStPatricksDay.WithAWhiskey();
        }
    }

    public static void WithAWhiskey()
    {
        if (CurrentCity.HasWhiskey &&
            !Me.PassedOut &&
            !Me.SickAsADog &&
             Me.HasMoney)
        {
            EnjoyStPatricksDay.WithAWhiskey();
        }
        else if (Me.HasMoney && !Me.PassedOut)
        {
            try
            {
                Me.EatFood();
            }
            catch (VomitException)
            {
            }
        }

        while (!Me.PassedOut)
        {
           try
           {
              Me.FindingWayBackToHotel();
           }
           catch (LostException)
           {
              Me.CatchTaxi();
           }
           finally
           {
              Me.Sleep();

              do
              {
                  Me.Snore();
              } while (Me.PassedOut);

              Me.DoHangover();
           }
        }
    }
}

Drink responsibly and have a great day!

A little help with GetHashCode

Implementing the GetHashCode override has proven to be a confusing issue as there are a lot of intricacies to following the rules. There have been plenty of blog posts and other discussions regarding when and how to follow the rules; I don't intend to cover that ground again. Instead, please take a look at some of these posts and discussions:

However, I thought I'd share something that I've found the following useful when implementing GetHashCode for my different types. The following static class encapsulates the algorithm recommended by Jon Skeet in this StackOverflow answer (though it can be found in other places too – it is also the algorithm used by the C# compiler when implementing GetHashCode for anonymous types, for example). This algorithm uses two prime numbers; one for the initial hash and the other as a multiplier when combining a hash code. These prime numbers are used to reduce hash code collisions, something that a basic XOR hash does not do.

My HashCode class extension methods use generics to avoid boxing for value types and also support combining the hash codes of collection elements, if this is needed.

//*****************************************************************************
//
//  Copyright © 2012 Jeff Yates
//
//*****************************************************************************
using System;
using System.Collections.Generic;

namespace SomewhatAbstract
{
    /// <summary>
    /// Provides extensions for producing hash codes to support overrides
    /// of <see cref="System.Object.GetHashCode"/>.
    /// </summary>
    public static class HashCode
    {
        /// <summary>
        /// Provides the initial value for a hash code.
        /// </summary>
        public static readonly int InitialHash = 17;
        private const int Multiplier = 37;

        /// <summary>
        /// Combines the hash code for the given value to an existing hash code
        /// and returns the hash code.
        /// </summary>
        /// <param name="code">The previous hash value.</param>
        /// <param name="value">The value to hash.</param>
        /// <returns>The new hash code.</returns>
        private static int Hash<T>(int code, T value)
        {
            int hash = 0;
            if (value != null)
            {
                hash = value.GetHashCode();
            }

            unchecked
            {
                code = (code * HashCode.Multiplier) + hash;
            }
            return code;
        }

        /// <summary>
        /// Combines the hash codes for the elements in the given sequence with an
        /// existing hash code and returns the hash code.
        /// </summary>
        /// <param name="code">The code.</param>
        /// <param name="sequence">The sequence.</param>
        /// <returns>The new hash code.</returns>
        public static int HashWithContentsOf<T>(this int code, IEnumerable<T> sequence)
        {
            foreach (T element in sequence)
            {
                code = code.HashWith(element);
            }
            return code;
        }

        /// <summary>
        /// Combines the given value's hash code with an existing hash code value.
        /// </summary>
        /// <typeparam name="T">The type of the value being hashed.</typeparam>
        /// <param name="code">The previous hash code.</param>
        /// <param name="value">The value to hash.</param>
        /// <returns>The new hash code.</returns>
        public static int HashWith<T>(this int code, T value)
        {
            return Hash(code, value);
        }
    }
}

Here is an example of how you might use these extension methods to implement an override of GetHashCode. It doesn't necessarily save any typing over just hand-implementing the algorithm, but I find it helps avoid inconsistencies and forgetfulness while giving a little clarity to the code.

public struct MyCustomType
{
    private readonly ReadOnlyCollection myListOfThings;
    private readonly bool aFlagOfSomething;
    private readonly object aThing;

    public override int GetHashCode()
    {
        return HashCode.InitialHash
            .HashWith(this.aFlagOfSomething)
            .HashWith(this.aThing)
            .HashWithContentsOf(this.myListOfThings);
    }
}

Let me know if you find this useful. Perhaps you have a different approach when implementing GetHashCode. If you do, I'd love to hear about it.