.NET 4中的IDictionary <TKey,TValue>不是协变的怎么办?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (9)

IDictionary<TKey, TValue>在.NET 4 / Silverlight 4中不支持的协方差,即我不能做

IDictionary<string, object> myDict = new Dictionary<string, string>();

类似于我IEnumerable<T>现在可以用s 做的事情。

大概归结KeyValuePair<TKey, TValue>为非协变。我认为字典中至少应该允许协变量的值。

那么这是一个错误还是一个功能?它会不会来,也许在.NET 37.4?

IReadOnlyDictionary<TKey, TValue>在.NET 4.5中会有一个,但它也不会是协变的:·/,因为它来自于IEnumerable<KeyValuePair<TKey, TValue>>,而KeyValuePair<TKey, TValue>不是一个接口,因此不可能是协变的。

BCL团队必须重新设计很多才能出现并使用一些ICovariantPair<TKey, TValue>this[TKey key]对于协变接口,强类型索引器也是不可能的。类似的结局只能通过在GetValue<>(this IReadOnlyDictionary<TKey, TValue> self, TKey key)某个地方放置一个扩展方法来实现,这个方法在某种程度上必须在内部被称为一个实际的实现,这可能看起来像一个相当混乱的方法。

提问于
用户回答回答于

这是一个功能。.NET 4.0只支持安全协方差。你提到的转换是潜在的危险,因为如果可能的话,你可以添加一个非字符串元素到字典中:

IDictionary<string, object> myDict = new Dictionary<string, string>();
myDict["hello"] = 5; // not an string

另一方面,它IEnumerable<T>是一个只读接口。该T类型参数仅在其输出位置(的返回类型Current属性),所以它是安全的治疗IEnumerable<string>作为IEnumerable<object>

用户回答回答于

但是你可以说

myDict.Add("Hello, world!", new DateTime(2010, 1, 27));

这会惨败。问题是,TValueIDictionary<TKey, TValue>被输入和输出位置使用。以机智:

myDict.Add(key, value);   

TValue value = myDict[key];

那么这是一个错误还是一个功能?

这是设计。

它会不会来,也许在.NET 37.4?

不,这本质上是不安全的。

扫码关注云+社区