开发者

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

开发者 https://www.devze.com 2022-12-09 14:33 出处:网络
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?!

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));
    }
}


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消