首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >嵌套接口: Cast IDictionary<TKey,IList<TValue>> to IDictionary<TKey,IEnumerable<TValue>>?

嵌套接口: Cast IDictionary<TKey,IList<TValue>> to IDictionary<TKey,IEnumerable<TValue>>?
EN

Stack Overflow用户
提问于 2012-05-01 23:00:08
回答 2查看 1.1K关注 0票数 2

我认为将IDictionary<TKey, IList<TValue>>对象强制转换为IDictionary<TKey, IEnumerable<TValue>>相当简单,但是

代码语言:javascript
运行
复制
var val = (IDictionary<TKey, IEnumerable<TValue>>)Value;

抛出System.InvalidCastException,然后

代码语言:javascript
运行
复制
var val = Value as IDictionary<TKey, IEnumerable<TValue>>;

使val为空。什么是正确的投射方式?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-01 23:03:51

我认为将IDictionary<TKey, IList<TValue>>对象转换为IDictionary<TKey, IEnumerable<TValue>>是相当简单的

绝对不是。它就不是类型安全的。这里有一个为什么不是这样的例子:

代码语言:javascript
运行
复制
// This is fine...
IDictionary<string, IList<int>> dictionary = new Dictionary<string, IList<int>>();

// Suppose this were valid...
IDictionary<string, IEnumerable<int>> badDictionary = dictionary;

// LinkedList<T> doesn't implement IList<T>
badDictionary["foo"] = new LinkedList<int>();

// What should happen now?
IList<int> bang = dictionary["foo"];

正如你所看到的,这会造成问题-当我们期望所有的值都实现IList<int>时,我们会试图得到一个LinkedList<int>。泛型的要点是类型安全--那么你认为哪一行会失败呢?对我来说,第一、第三和第四行看起来非常有效-所以第二行是唯一不能编译的,它编译失败了……

现在,在某些情况下,它可以安全地完成。例如,您可以(在C# 4中)将IEnumerable<string>转换为IEnumerable<object>,因为IEnumerable<T>只在“输出”位置使用T

有关更多详细信息,请参阅MSDN

编辑:只是为了澄清-使用现有键/值对的副本创建新字典很容易,例如使用link:

代码语言:javascript
运行
复制
var copy = original.ToDictionary<TKey, IEnumerable<TValue>>(pair => pair.Key,
                                                            pair => pair.Value);

您只需要知道,您现在有两个独立的字典。

票数 8
EN

Stack Overflow用户

发布于 2012-05-12 08:46:11

这可能对你有帮助,也可能没有帮助,但我想我应该把它作为Jon答案的补充。

如果您只需要字典的值,而不引用它们的键,则可以这样做:

代码语言:javascript
运行
复制
IDictionary<TKey, IList<TValue>> dictionary = Whatever();
var values = (IEnumerable<IEnumerable<TValue>>)dictionary.Values;

要使其起作用,您必须使用C# 4.0或更高版本,并且必须将TValue约束为引用类型。下面是代码,稍微进行了重构,并带有注释进行解释:

代码语言:javascript
运行
复制
IDictionary<TKey, IList<TValue>> dictionary = Whatever();

//Values returns an ICollection<IList<TValue>>
ICollection<IList<TValue>> temp1 = dictionary.Values;

//ICollection<T> inherits from IEnumerable<T>
IEnumerable<IList<TValue>> temp2 = temp1;

//IEnumerable<T> is covariant
//There is an implicit reference conversion between IList<T> and IEnumerable<T>
//So there is an implicit reference conversion between IEnumerable<IList<T>>
//and IEnumerable<IEnumerable<T>>
IEnumerable<IEnumerable<TValue>> values = temp2;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10399568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档