Is it OK to pass a generic Dictionary as a param to a method expecting IDictionary

AssemblyInstaller.Install expects a System.Collections.IDictionary.

Am I right to be 'allergic' to using non-generic collections such as Hashtable or should I get over myself?!

e.g.

using System.Collections.Generic;
using System.Configuration.Install;
using System.Reflection;
using AssemblyWithInstaller;

namespace InstallerDemo
{
    class InstallerDemo
    {
        static void Main(string[] args)
        {
            var savedState = new Dictionary<object, object>();
            // i.e. as opposed to something that implements IDictionary:
            //var savedState = new System.Collections.Hashtable()
            var assembly = Assembly.GetAssembly(typeof (MyInstaller));
            var ai = new AssemblyInstaller(assembly, new[] {"/LogFile=install.log"});
            ai.Install(savedState);
            ai.Commit(savedState);
        }
    }
}

Additionally the compiler has no issue with this decalration:

var savedState = new Dictionary<string, object>();

But will anything bad happen at runtime if someone uses something other than strings as keys?


Update [Reflector to the rescue]

var savedState = new Dictionary<string, object>();

Confirming what Jon says, Dictionary implements IDictionary as follows:

void IDictionary.Add(object key, object value)
{
    Dictionary<TKey, TValue>.VerifyKey(key);
    Dictionary<TKey, TValue>.VerifyValueType(value);
    this.Add((TKey) key, (TValue) value);
}

...so in verifying the key it will throw an exception when the type of the key doesn't match that used when declaring the particular specialization of the generic Dictionary (and likewise for the type of the value):

private static void VerifyKey(object key)
{
    if (key == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
    }
    if (!(key is TKey))
    {
        ThrowHelper.ThrowWrongKeyTypeArgumentException(key, typeof(TKey));
    }
}

Answers


This works because Dictionary<TKey, TValue> implements IDictionary - but it will indeed fail at execution time if someone calls IDictionary.Add(object, object) with a non-string key - you'll get an ArgumentException.

Note that the IDictionary<TKey, TValue> interface itself doesn't extend IDictionary - it's just that the Dictionary<TKey, TValue> implementation also implements IDictionary.


Since the Installer is accepting an IDictionary-Object, it should be able to deal with any Dictionary passed to him. At least that's my opinion...if I take an Interface, I need to be able the handle any implementation of it.

Also, I'd suggest that you just try it.


Need Your Help

checkout out local, which path should I use

mercurial continuous-integration windows-server-2008 bamboo

I have a mercurial repository that is not accessible by Http. I can't figure out how I should configure the path in my continuous integration tool (bamboo), before my repo was hosted co-located and...

z-index doesn't work properly

html css z-index

I have problem with setting z-index in 3 containers.