本文完美地描述了在你的代码中遇到的情况。
点击
Dictionary<TKey, TValue> 能够实现 IReadOnlyDictionary<TKey, TValue>,因为任何使用后者的代码都承诺不修改字典,这是前者提供的功能子集。
但是考虑另一个方向。你从一个 IReadOnlyDictionary<TKey, TValue> 开始,尝试将其转换为常规的 Dictionary<TKey, TValue>。现在,你已经拿走了之前承诺不会被修改的东西,并将其变成了可能被修改的东西。
显然,这行不通。
此外,你不能仅仅假设只读实现在被修改时会抛出异常或其他错误(例如运行时安全性而非编译时安全性),因为正如你所知,你总是可以从可变的实现中获取只读接口。
因此,为了安全起见,你有两个选择:
只需将整个字典内容复制到一个新对象中。
将只读对象包装在一个IDictionary<TKey,TValue>实现中,如果您尝试修改它,则会引发异常。
请注意,后者实际上并没有给您您特别要求的内容。它很接近,但它不是Dictionary<TKey,TValue>的实例。
在复制方面,您有许多选择。就我个人而言,我认为ToDictionary()本身就很好。但是,如果您真的不喜欢冗长,可以将其包装在扩展方法中:
public static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>(
this IReadOnlyDictionary<TKey, TValue> dictionary)
{
return dictionary.ToDictionary(x => x.Key, y => y.Value);
}
IReadOnlyCollection<T>
并不意味着集合是只读的,只是接口被限制为只读。 - Jon Skeet