是否可以将通用字典作为参数传递给期望IDictionary的方法

时间:2009-10-29 09:22:51

标签: c# generics collections

AssemblyInstaller.Install需要一个System.Collections.IDictionary。

我是否对使用Hashtable等非通用集合感到'过敏',或者我应该克服自己?!

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

此外,编译器对此decalration没有任何问题:

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

但是如果有人使用字符串以外的东西作为键,那么在运行时会发生什么不好的事吗?


更新 [反射器救援]

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

确认Jon所说的内容,Dictionary实现IDictionary如下:

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

...因此,在验证密钥时,如果密钥的类型与声明泛型字典的特定特化(以及类似值的类型)时使用的密钥类型不匹配,它将抛出异常:

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

2 个答案:

答案 0 :(得分:4)

由于安装程序正在接受IDictionary-Object,它应该能够处理传递给他的任何字典。至少我的意见是......如果我接受一个接口,我需要能够处理它的任何实现。

另外,我建议你试试吧。

答案 1 :(得分:2)

这是有效的,因为Dictionary<TKey, TValue>实现了IDictionary - 但如果有人用非字符串键调用IDictionary.Add(object, object),它确实会在执行时失败 - 你会得到一个{{1} }。

请注意,IDictionary<TKey, TValue>界面本身并未扩展ArgumentException - 只是IDictionary实现实现了Dictionary<TKey, TValue>