【问题标题】:Is it OK to pass a generic Dictionary as a param to a method expecting IDictionary可以将通用字典作为参数传递给期望 IDictionary 的方法吗
【发布时间】:2009-10-29 09:22:50
【问题描述】:

AssemblyInstaller.Install 需要 System.Collections.IDictionary。

我对使用 Hashtable 等非泛型集合“过敏”是对的还是我应该克服自己?!

例如

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

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

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

【问题讨论】:

    标签: c# generics collections


    【解决方案1】:

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

    另外,我建议你试试看。

    【讨论】:

    • 我们不能指望遗留代码知道泛型。它将调用 Add(object, object) 并且我的实现需要一个字符串键,所以我试图考虑是否存在在运行时会出现问题的情况。
    • 无论如何,谢谢鲍比。我会试试这个并用我的结果更新问题。
    【解决方案2】:

    这是可行的,因为 Dictionary&lt;TKey, TValue&gt; 实现了 IDictionary - 但如果有人使用非字符串键调用 IDictionary.Add(object, object),它确实会在执行时失败 - 你会得到一个 ArgumentException

    注意IDictionary&lt;TKey, TValue&gt; 接口本身并没有扩展IDictionary - 只是Dictionary&lt;TKey, TValue&gt; 实现 实现了IDictionary

    【讨论】:

    • 好的,很高兴知道,谢谢。但是你对我更喜欢 Dictionary 是否比 HashTable 更好有什么看法?至少通过这种方式,我可以更好地沟通,我(现在知道)是 IDictionary 的这种特殊用法的要求(即它实际上应该使用字符串键和对象值)。
    • 这取决于您喜欢检测错误的方式和时间。如果您很高兴当有人尝试添加非字符串键时它立即“爆炸”,那么我认为这是一个好计划。
    • 所以我想我们应该只在我们自己编写安装程序时才考虑这样做,或者我们知道假设将使用字符串键是可以的......
    猜你喜欢
    • 2010-09-28
    • 1970-01-01
    • 2015-12-29
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 2012-11-17
    相关资源
    最近更新 更多