IDictionary<TKey,TValue>在 .NET 4 中不是协变的 [英] IDictionary<TKey, TValue> in .NET 4 not covariant
问题描述
.NET 4/Silverlight 4 中的 IDictionary
不支持协方差,即我做不到
The IDictionary<TKey, TValue>
in .NET 4 / Silverlight 4 does not support covariance, i.e. I can't do a
IDictionary<string, object> myDict = new Dictionary<string, string>();
类似于我现在可以用 IEnumerable
做的事情.
analog to what I can do with IEnumerable<T>
s now.
可能归结为 KeyValuePair
也不是协变的.我觉得字典中应该允许协方差,至少对于这些值.
Probably boils down to the KeyValuePair<TKey, TValue>
not being covariant either. I feel that covariance should be allowed in dictionaries at least for the values.
这是错误还是功能?它会不会出现,也许在 .NET 37.4 中?
So is that a bug or a feature? Will it ever come, maybe in .NET 37.4?
更新(2 年后):
将会有一个 IReadOnlyDictionary<.NET 4.5 中的 TKey, TValue>
,但它也不会协变 :·/
,因为它派生自 IEnumerable
和 KeyValuePair
不是接口,因此不能协变.
There will be an IReadOnlyDictionary<TKey, TValue>
in .NET 4.5, but it won't be covariant either :·/
, because it derives from IEnumerable<KeyValuePair<TKey, TValue>>
, and KeyValuePair<TKey, TValue>
is not an interface and thus cannot be covariant.
BCL 团队必须重新设计很多东西才能提出并使用一些 ICovariantPair
代替.协变接口也不可能使用强类型索引器 á la this[TKey key]
.类似的结果只能通过将扩展方法 GetValue<>(this IReadOnlyDictionary<TKey, TValue> self, TKey key)
放置在某处以某种方式在内部必须调用实际实现来实现,它可以说看起来是一个相当混乱的方法.
The BCL team would have to redesign a lot to come up and use some ICovariantPair<TKey, TValue>
instead. Also strongly-typed indexers á la this[TKey key]
aren't possible for covariant interfaces. A similar end can only be achieved by placing an extension method GetValue<>(this IReadOnlyDictionary<TKey, TValue> self, TKey key)
somewhere which would somehow internally have to call an an actual implementation, which arguably looks like a quite messy approach.
推荐答案
这是一个功能..NET 4.0 仅支持安全协变.您提到的演员表有潜在危险,因为您可以在可能的情况下向字典添加非字符串元素:
It's a feature. .NET 4.0 only supports safe covariance. The cast you mentioned is potentially dangerous as you could add a non-string element to the dictionary if that was possible:
IDictionary<string, object> myDict = new Dictionary<string, string>();
myDict["hello"] = 5; // not an string
另一方面,IEnumerable
是一个只读接口.T
类型参数仅在其输出位置(Current
属性的返回类型),因此可以安全地将 IEnumerable
视为IEnumerable
.
On the other hand, IEnumerable<T>
is a read-only interface. The T
type parameter is only in its output positions (return type of the Current
property) so it's safe to treat IEnumerable<string>
as an IEnumerable<object>
.
这篇关于IDictionary<TKey,TValue>在 .NET 4 中不是协变的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!