IReadOnlyDictionary的键和值的数据类型

时间:2016-05-16 20:57:00

标签: c# .net interface

对于IDictionary<TKey, TValue>KeysValues属性的类型为ICollection<TKey>ICollection<TValue>

对于IReadonlyDictionary<TKey, TValue>KeysValues属性的类型为IEnumerable<TKey>IEnumerable<Value>

为什么IReadonlyDictionary<TKey, TValue>的属性不仅仅是相应的ReadOnly接口,即IReadOnlyCollection<TKey>IReadOnlyCollection<TValue>

有人可能想知道为什么两个属性都不是IEnumerable类型,因为你不能通过两个属性改变字典,而是通过AddRemove方法。实际上ICollection返回的IDictionary.Keys具有IsReadOnly属性集,因此尝试在属性上调用AddRemove会抛出NotSupportedException附加信息不允许变异从字典派生的密钥集合。

如果一个人无法通过其属性改变字典,为什么不是IReadOnlyCollections两者? IReadOnly接口最初是在.NET 4.5中引入的,所以我想如果没有不希望的向后兼容性破坏就无法完成。

3 个答案:

答案 0 :(得分:1)

如果他们不想使用IReadonlyDictionary<TKey, TValue>派生的内容作为后备商店,那么实施自定义IReadOnlyCollection的人就会减轻负担。

如果您使用的是ReadOnlyDictionary的内置实现,则无法阻止您转换界面。

IReadOnlyDictionary<Foo, Bar> baz = GetDictionary();

IEnumerable<Foo> keys = baz.Keys;
IReadOnlyCollection<Foo> keysCollection = keys as IReadOnlyCollection<Foo>;

if(keysCollection != null)
{
    //This code will execute for the built in implmentation of `ReadOnlyDictionary<Foo, Bar>`
}

答案 1 :(得分:1)

您不会通过KeysValues属性修改键集合或值集合。您只能使用这些属性来访问键和值。因此,它们是否是明确的只读集合并不重要。

只能通过向字典中添加项目来修改键和值,而使用IReadOnlyDictionary无法做到这一点。

此外,使用ICollection会对IReadOnlyDictionary的特定实现如何返回这些属性施加额外限制。 IEnumerable<T>可以通过多种方式实现,即使是使用yield语句的方法也是如此。如果返回的类型是ICollection<T>,那么字典将被强制填充实现ICollection<T>的内容。它可能仍然会这样做,但如果某些内容实现了ICollection<T>,那么它也会实现IEnumerable<T>

所以我想知道另一种方式 - 为什么IDictionary<T>会为这些属性而不是ICollection<T>返回IEnumerable<T>。 (可能有一个很好的理由。但现在我想知道。)

答案 2 :(得分:0)

IEnumerable<T>允许您直接利用Linq方法和整个迭代器基础结构,而无需执行强制转换。

即使通过ReadOnlyDictionaryKey集合,您也无法修改基础Value实施中的数据。 IEnumerable<T>并不关心其底层实现是否为只读。