当值类型可以相互转换时,为什么我不能将一种值类型的字典转换为另一种值类型的字典? [英] 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?

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

问题描述

可能的重复:
在 C# 中,为什么不能't a Listobject 存储在 List 中.变量

为什么下面的方法不起作用?

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

这是 Dictionary 转换机制的缺陷,还是我认为应该允许这样做?

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

谢谢.

推荐答案

这是字典转换机制的缺陷,还是我认为应该允许这样做?

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!

字符串数组可转换为IEnumerable,但不能转换为List.您只需将不是字符串列表的内容放入只能取字符串列表的字典中.

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.

在 C# 中,如果满足以下所有条件,泛型类型可能是协变的或逆变的:

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

  • 您使用的是 C# 4 或更高版本.
  • 不同的泛型类型是接口或委托.
  • 可证明该方差是类型安全的.(C# 规范描述了我们用来确定方差安全的规则.可以下载 C# 4.0 版本的文档文件 [此处].参见第 23.5 节.)
  • 变化的类型参数都是引用类型.
  • 该类型已被明确标记为安全的变异.
  • 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 确实满足所有这些条件.您可以在 C# 4 中将 IEnumerable 转换为 IEnumerable.

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/标签/协方差+和+逆变/

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

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