Type-safe Dictionary for various types Assume the following situation: you have an object that can store any object based on a key (basically, IDictionary&lt;string, object&gt;). You want to store objects of various types into it that are not directly related. (For example, the dictionary can be an ASP.NET Session, or it can represent a dictionary that will be serialized to disk for persistent storage.)

I don't want to create a single class that will contain all those objects, because they are not directly related, they come from different places. But if you store each object separately, it means you have to use casts when getting some value and there is no type-check when you're setting it.

To solve this, I created a generic type that encapsulates the key along with the associated type and a couple of extension methods that use it:

class TypedKey&lt;T&gt;
{
    public string Name { get; private set; }

    public TypedKey(string name)
    {
        Name = name;
    }
}

static class DictionaryExtensions
{
    public static T Get&lt;T&gt;(this IDictionary&lt;string, object&gt; dictionary, TypedKey&lt;T&gt; key)
    {
        return (T)dictionary[key.Name];
    }

    public static void Set&lt;T&gt;(this IDictionary&lt;string, object&gt; dictionary, TypedKey&lt;T&gt; key, T value)
    {
        dictionary[key.Name] = value;
    }
}


Usage:

private static readonly TypedKey&lt;int&gt; AgeKey = new TypedKey&lt;int&gt;("age");

…

dictionary.Get(AgeKey) &gt; 18
dictionary.Set(AgeKey, age)


This has the type-safety (both on get and set) of using a property, while being backed by a dictionary that can store anything.

What do you think about this pattern?
Your suggestion is not really type-safe as you can still pass a key of the wrong type. Therefore I would just use a normal (string) key. But I would add a generic TryGet method which takes account of the type. The setter needs not to be generic. 

static class DictionaryExtensions
{
    public static T Get&lt;T&gt;(this IDictionary&lt;string, object&gt; dictionary, string key)
    {
        return (T)dictionary[key];
    }

    public static bool TryGet&lt;T&gt;(this IDictionary&lt;string, object&gt; dictionary,
                                 string key, out T value)
    {
        object result;
        if (dictionary.TryGetValue(key, out result) &amp;&amp; result is T) {
            value = (T)result;
            return true;
        }
        value = default(T);
        return false;
    }

    public static void Set(this IDictionary&lt;string, object&gt; dictionary,
                           string key, object value)
    {
        dictionary[key] = value;
    }
}


You can then use the dictionary like this.

int age = 20;
dictionary.Set("age", age);

// ...

age = dictionary.Get&lt;int&gt;("age");

// or the safe way
if (dictionary.TryGet("age", out age)) {
    Console.WriteLine("The age is {0}", age);
} else {
    Console.WriteLine("Age not found or of wrong type");
}


Note that the compiler can infer the generic type when using TryGet.



UPDATE

In despite of my suggestion above, I must agree that your solution is elegant. Here is another suggestion which is based on your solution but which encapsulates the dictionary instead of providing a key. Well, it acts as wrapper and as key at the same time

public class Property&lt;T&gt;
{
    Dictionary&lt;object, object&gt; _dict;

    public Property (Dictionary&lt;object, object&gt; dict)
    {
        _dict = dict;
    }

    public T Value {
        get { return (T)_dict[this]; }
        set { _dict[this] = value; }
    }
}


Alternatively, a string key could be provided in the Property's constructor.

You can use it like this

private static readonly Dictionary&lt;object, object&gt; _properties = 
    new Dictionary&lt;object, object&gt;();
private static readonly Property&lt;int&gt; _age = new Property&lt;int&gt;(_properties);

...

_age.Value &gt; 18
_age.Value = age