.NET 4.5引入了方便的IReadOnlyDictionary<TKey, TValue>接口(interface)。 Dictionary<TKey, TValue>是-IReadOnlyDictionary<TKey, TValue>,因此我可以将前者传递到需要后者的地方。

但是,我不确定相反的方式:如何基于现有Dictionary<,>创建新的IReadOnlyDictionary<,>

  • Dictionary<,>有几个采用IDictionary<,>的构造函数-但没有一个采用IReadOnlyDictionary<,>的构造函数。
  • IReadOnlyDictionary<,>具有扩展方法ToDictionary<,>()。但是,这是从IEnumerable<>继承的。因此,要使用它,我必须像这样传递两个完全多余的委托(delegate):readOnlyDict.ToDictionary(pair => pair.Key, pair => pair.Value)。丑陋!
  • 当然,我总是可以创建一个新的Dictionary<,>,遍历原始对并复制它们。

  • 在我看来,应该有一种简单的方法来基于现有的Dictionary<,>创建新的IReadOnlyDictionary<,>。我想念什么吗?

    编辑:一些澄清。我不是在寻找将IReadOnlyDictionary<,>当作Dictionary<,>的魔术方法。我想创建一个新的Dictionary<,>,从IReadOnlyDictionary<,>复制其初始值。这个问题是一个漫长的询问方式:
    Dictionary<,>具有便捷的构造函数,可从IDictionary<,>复制初始值。为什么没有人使用IReadOnlyDictionary<,>?获得相同结果的最惯用的方法是什么?

    最佳答案

    Dictionary<TKey, TValue>能够实现IReadOnlyDictionary<TKey, TValue>,因为采用后者的任何代码都 promise 不会修改字典,而字典是前者提供的功能的子集。

    但是请考虑另一个方向。您从IReadOnlyDictionary<TKey, TValue>开始,然后尝试将其变成常规的Dictionary<TKey, TValue>。现在,您已经采用了以前 promise 不会进行修改的内容,并将其变成了可以修改的内容。

    显然,那是行不通的。

    此外,您不能仅仅假设只读实现在修改后会抛出异常或其他异常(例如,运行时安全,即使不是编译时安全),因为您知道,您始终可以获取只读可变实现的接口(interface)。

    为了安全起见,您有两种选择:

  • 只需将整个词典内容复制到一个新对象中即可。
  • 将只读对象包装在IDictionary<TKey, TValue>实现中,如果您尝试修改它,该对象确实会引发异常。

  • 请注意,后者实际上并不能满足您的具体要求。它很接近,但不是Dictionary<TKey, TValue>的实际实例。

    在复制方面,您有很多选择。我个人认为ToDictionary()本身就很好。但是,如果您真的不喜欢冗长,可以将其包装在扩展方法中:
    public static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>(
        this IReadOnlyDictionary<TKey, TValue> dict)
    {
        return dict.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
    }
    

    附录:
    在我看来,我可能应该澄清一下:以上所有假定您都在尝试转换IReadOnlyDictionary<TKey, TValue>的任意实例。显然,如果您知道或至少怀疑IReadOnlyDictionary<TKey, TValue>对象实际上是Dictionary<TKey, TValue>的实例,则可以强制转换或尝试分别强制转换为Dictionary<TKey, TValue>

    关于c# - 如何从IReadOnlyDictionary <,>创建新的Dictionary <,>?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28669904/

    10-12 23:48