为什么我不能投一个值类型的字典到另一个值类型的字典时的值类型可以相互定投? [英] Why can't I cast a dictionary of one value type to dictionary of another value type when the value types can be cast from one another?

查看:129
本文介绍了为什么我不能投一个值类型的字典到另一个值类型的字典时的值类型可以相互定投?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:结果
在C#中,为什么不能一名单<串GT;对象被存储在一个列表与所述;对象>可变






为什么没有下文的工作?



 列表<串GT; castMe =新的List<串GT;(); 
IEnumerable的<串GT; getFromCast =(IEnumerable的<串GT;)castMe; //允许的。

&字典LT; INT,列表与LT;串GT;> castMeDict =新词典< INT,列表与LT;串GT;>();
&字典LT; INT,IEnumerable的<串GT;> getFromDict =(词典< INT,IEnumerable的<串GT;>)castMeDict; //不允许

这是在词典缺陷铸造机制,或者在我的思想,这应该被允许?



感谢。


解决方案

这是字典中铸造机制的缺陷,或在我的思想,这应该被允许?




在你的思维。你期望的字典应的的在他们的转换。它们都没有,由于以下原因。假设他们,并推断这可能出问题:

 词典< INT,列表与LT;串>> castMeDict = 
新字典< INT,列表与LT;串GT;>();

&字典LT; INT,IEnumerable的<串GT;> getFromDict =
(词典< INT,IEnumerable的<串GT;>)castMeDict;

castMeDict [123] =新的List<串GT;();
IEnumerable的<串GT;串= getFromDict [123]; // 没问题!
getFromDict [123] =新的String [] {你好}; // 大问题!



字符串数组可以转换为的IEnumerable<串> 而不是列表<串GT; 。你只要把东西是的的字符串转换成字典,只能采取字符串列表清单。



在C#泛型类型可能是协变或逆变如果满足下列所有条件都满足:




  • 您正在使用C#4或更好

  • 的不同泛型类型是一个接口或委托。

  • 的变化可证明是类型安全的。 (C#的规范描述,我们用它来确定方差的安全规则。C#4.0版本doc文件可以下载的 [这里] 。见23.5。)

  • 的类型参数的变化都是引用类型。

  • 类型已专门标记为方差安全



大多数这些条件没有得到满足的字典 - 它不是接口或委托,它不是可证明安全的,并且类型未标记为方差为安全的。所以,没有方差字典



的IEnumerable< T> 相比之下并不满足所有这些条件。您可以将的IEnumerable<串> 的IEnumerable<对象> 在C#4



如果方差的主题感兴趣,可以阅读我的​​二十几文章的主题:



http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/


Possible Duplicate:
In C#, why can't a List<string> object be stored in a List<object> variable

Why doesn't the below work?

List<string> castMe = new List<string>();
IEnumerable<string> getFromCast  = (IEnumerable<string>)castMe; // allowed.

Dictionary<int, List<string>> castMeDict = new Dictionary<int, List<string>>();
Dictionary<int, IEnumerable<string>> getFromDict = (Dictionary<int, IEnumerable<string>>)castMeDict;  // Not allowed

Is this a flaw in the Dictionary casting mechanism, or in my thinking that this should be allowed?

Thanks.

解决方案

Is this a flaw in the Dictionary casting mechanism, or in my thinking that this should be allowed?

In your thinking. You are expecting that dictionaries should be covariant in their conversions. They are not, for the following reason. Suppose they were, and deduce what could go wrong:

Dictionary<int, List<string>> castMeDict = 
    new Dictionary<int, List<string>>();

Dictionary<int, IEnumerable<string>> getFromDict = 
    (Dictionary<int, IEnumerable<string>>)castMeDict;

castMeDict[123] = new List<string>();
IEnumerable<string> strings = getFromDict[123]; // No problem!
getFromDict[123] = new string[] { "hello" }; // Big problem!

An array of string is convertible to IEnumerable<string> but not to List<string>. You just put something that is not a list of string into a dictionary that can only take list of string.

In C# generic types may be covariant or contravariant if all the following conditions are met:

  • You're using C# 4 or better.
  • The varying generic type is an interface or delegate.
  • The variance is provably typesafe. (The C# specification describes the rules we use to determine variance safety. C# 4.0 Version doc file can be downloaded [here]. See section 23.5.)
  • The type arguments that vary are all reference types.
  • The type has been specifically marked as safe for variance.

Most of those conditions are not met for dictionary -- it is not an interface or delegate, it is not provably safe, and the type is not marked as safe for variance. So, no variance for dictionaries.

IEnumerable<T> by contrast does meet all those conditions. You can convert IEnumerable<string> to IEnumerable<object> in C# 4.

If the subject of variance interests you, consider reading my two dozen articles on the subject:

http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/

这篇关于为什么我不能投一个值类型的字典到另一个值类型的字典时的值类型可以相互定投?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆