C# IReadOnlyDictionary的键和值的数据类型

C# IReadOnlyDictionary的键和值的数据类型,c#,.net,interface,C#,.net,Interface,对于IDictionary而言,键和值属性的类型为ICollection和ICollection 对于IReadonlyDictionary而言,键和值属性的类型为IEnumerable和IEnumerable 为什么IReadonlyDictionary的属性不只是相应的只读接口,即IReadOnlyCollection和IReadOnlyCollection 有人可能想知道为什么这两个属性都不是IEnumerable类型,因为您不能通过这两个属性而通过Add和Remove方法来更改字典。事实

对于
IDictionary
而言,
属性的类型为
ICollection
ICollection

对于
IReadonlyDictionary
而言,
属性的类型为
IEnumerable
IEnumerable

为什么
IReadonlyDictionary
的属性不只是相应的只读接口,即
IReadOnlyCollection
IReadOnlyCollection

有人可能想知道为什么这两个属性都不是
IEnumerable
类型,因为您不能通过这两个属性而通过
Add
Remove
方法来更改字典。事实上,
IDictionary.Keys
返回的
ICollection
具有
IsReadOnly
属性集,因此尝试调用属性上的
Add
Remove
会抛出一个
NotSupportedException
,其中附加的信息是不允许对派生自字典的密钥集合进行变异

如果一个人无论如何都不能通过它的属性来修改字典,为什么两个
IReadOnlyCollections

IReadoly
接口最初是在.NET 4.5中引入的,因此,我想,如果人们不想将源自
IReadOnlyCollection
的内容用作其后台存储,那么实现自定义
IReadonlyDictionary
的人就不会有太多负担

如果您使用的是
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>`
}
IReadOnlyDictionary baz=GetDictionary();
IEnumerable keys=baz.keys;
IReadOnlyCollection keysCollection=作为IReadOnlyCollection的键;
if(keysCollection!=null)
{
//此代码将为内置的“ReadOnlyDictionary”实现执行`
}

如果人们不想将源自
IReadOnlyCollection
的内容用于其后台存储,那么实现自定义
IReadonlyDictionary
的人的负担就会减轻

如果您使用的是
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>`
}
IReadOnlyDictionary baz=GetDictionary();
IEnumerable keys=baz.keys;
IReadOnlyCollection keysCollection=作为IReadOnlyCollection的键;
if(keysCollection!=null)
{
//此代码将为内置的“ReadOnlyDictionary”实现执行`
}

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

只能通过向字典中添加项来修改键和值,这是使用
IReadOnlyDictionary
无法做到的

此外,使用
ICollection
IReadOnlyDictionary
的特定实现如何返回这些属性进行了额外的限制。
IEnumerable
可以用更多的方式实现,甚至可以通过使用
yield
语句的方法来实现。如果返回的类型是
ICollection
,那么字典将被迫填充实现
ICollection
的内容。它可能仍然会这样做,但是如果某个东西实现了
ICollection
,那么它也实现了
IEnumerable


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

您不需要通过
属性修改键集合或值集合。您只能使用这些属性访问键和值。因此,它们是否是显式只读集合并不重要

只能通过向字典中添加项来修改键和值,这是使用
IReadOnlyDictionary
无法做到的

此外,使用
ICollection
IReadOnlyDictionary
的特定实现如何返回这些属性进行了额外的限制。
IEnumerable
可以用更多的方式实现,甚至可以通过使用
yield
语句的方法来实现。如果返回的类型是
ICollection
,那么字典将被迫填充实现
ICollection
的内容。它可能仍然会这样做,但是如果某个东西实现了
ICollection
,那么它也实现了
IEnumerable

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

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

即使通过
集合,也无法修改基础
ReadOnlyDictionary
实现中的数据
IEnumerable
不关心其底层实现是否为只读。

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


即使通过
集合,也无法修改基础
ReadOnlyDictionary
实现中的数据
IEnumerable
不关心其底层实现是否为只读。

这有点迟钝。你是说