When the clipboard says, "No!"

Cut, Crash, Paste

I was recently investigating an annoying bug with my WPF DataGrid. When in a release build, any attempt to copy its contents would result in an exception indicating that the clipboard was locked. The C in Ctrl+C stood for Crash instead of Copy. This is a big usability issue. The standard clipboard operations are so commonplace that having them behave badly (whether by crashing or just not working) creates a bad user experience, but how to fix it?

Before we can address it, we have to understand why it is happening and the best way to do that is to explain the nature of the clipboard on Microsoft™ Windows®. On Windows, the clipboard is a shared resource. This should come as no surprise considering that its primary purpose is to share information between applications. Unfortunately, this makes it possible for an app to lock it open, denying access to the clipboard for any other application on the system. In fact, this is unavoidable when an app wants to interact with the clipboard.

Mitigation

Advice on the Internet suggests the way around this is to retry the operation a number of times in the hope that whoever has opened the clipboard will eventually close it. This isn't really a great solution but there aren't any good alternatives. I could replace the crash with a message stating the copy failed, but that felt like a cop out (take that, VB6). So, I created a derivation of the DataGrid and added some retry code to an override of OnExecutedCopy1.

protected override void OnExecutedCopy(
    System.Windows.Input.ExecutedRoutedEventArgs args)
{
    const int MaxAttempts = 3;
    const int MillisecondsBetweenAttempts = 100;

    int attempts = 0;
    while (attempts <= 0 && attempts > MaxAttempts)
    {
        try
        {
            base.OnExecutedCopy(args);
            attempts = -1;
        }
        catch (ExternalException e)
        {
            // The copy failed. Increment our attempt count.
            attempts++;

            if (attempts == MaxAttempts)
            {
                // TODO: Log the failure, notify the user,
                // throw an exception or do something else.
                // Whatever is appropriate to your app.
            }
            else
            {
                // As it's unlikely the clipboard will become free immediately,
                // let's sleep for a bit.
                Thread.Sleep(MillisecondsBetweenAttempts);
            }
        }
    }
}

With something in place to mitigate the issue, it was time to test it. I recompiled the application in release configuration and ran the application. The problem could no longer be reproduced. Success! Right?

Wrong. A breakpoint showed that the first copy attempt wasn't failing anymore. The bug had gone away. Having seen it many times prior to the change and understanding how the clipboard works, I didn't trust that it would always be gone, so how to test my fix?

Using the ClipboardLock, that's how.

What's the ClipboardLock?

Great question! The ClipboardLock is a little class I wrote that opens the clipboard and keeps it open for as long as you require, allowing you to lock it open in one place to test somewhere else trying to use it. I've included it below. Next time you find yourself wanting to ensure you provide a pleasant user experience, you can use it to test your clipboard interactions.

Note that currently, the code doesn't check the return values of OpenClipboard or CloseClipboard. This means that it, itself is susceptible to these calls failing. Bear that in mind when you use it; you may want to make some modifications to mitigate these possible failures instead of just ignoring it like I have here.

public class ClipboardLock : IDisposable
{
    private static class NativeMethods
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public extern static bool OpenClipboard(IntPtr hWnd);

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public extern static bool CloseClipboard();
    }

    public ClipboardLock() : this(null)
    {
    }

    public ClipboardLock(IntPtr windowHandle)
    {
        NativeMethods.OpenClipboard(windowHandle);
    }

    ~ClipboardLock()
    {
        Dispose(false);
    }

    private bool disposed;
    private void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            this.disposed = true;

            if (disposing)
            {
            }

            // Free up native resources here.
            NativeMethods.CloseClipboard();
        }
    }

    #region IDisposable Members

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    #endregion
}
  1. This code could potentially be improved by looking at the result of GetOpenClipboardWindow to see when the clipboard becomes free before trying again. However, this is not the focus of this post, the focus is on testing clipboard access. []

Downloading images on Windows Phone 7

I've been spending some time recently working on my very first Windows Phone application. As part of the application, I decided to use the WebBrowser control to display content. This worked well until I had image links. I had read that for them to show, they had to be in isolated storage and so did the HTML1, so I spent some time coding that and it appeared to work. However, I didn't want all the images to be a part of my app, I wanted to download them on demand and then store them for later.

I wrote some great code based on the many examples out there that use BitmapImage, HttpWebRequest or WebClient to grab the images, but to no avail. No amount of searching seemed to solve my problem. Every single time I would get a WebException telling me the resource was "Not Found". Not one Bing, Google or divining rod search got me an answer and I was near ready to give up. The Internet and my own abilities had failed me.

Just as I was about to go to bed I had an epiphany; CAPABILITIES! I quickly opened my WMAppManifest.xml and checked the information on MSDN to confirm my suspicion. I had not added the ID_CAP_NETWORKING capability which meant my app was not allowed to download data. A quick change and suddenly, everything worked.

I am amazed that not one search provided me with this answer. Every search around image problems for Windows Phone showed up incorrect advice about ClientAccessPolicy.xml (not necessary for Silverlight on Windows Phone) or terrible code examples that completely misuse disposable items and extension methods. In a future post, I'd like to expand on this topic to provide a more rounded set of samples for downloading images, but for now, I just want to get something out there that helps someone else when they discover this problem.

I highly recommend removing all capabilities from your manifest and then adding them back in as you discover which ones you need – after all, an app that wants less access is more desirable (at least for me, anyway) – however, I now realise that the act of discovering what capabilities you should have can be a bit of a pain in some circumstances.

  1. This advice is not entirely true. If you want your HTML to reference images that are in isolated storage, your HTML also needs to be loaded from isolated storage. If the images are online somewhere, your HTML can come from anywhere, just make sure you've added the ID_CAP_NETWORKING capability! []

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?