简体   繁体   English

嵌套接口:演员表IDictionary <TKey, IList<TValue> &gt;到IDictionary <TKey, IEnumerable<TValue> &gt;?

[英]Nested Interfaces: Cast IDictionary<TKey, IList<TValue>> to IDictionary<TKey, IEnumerable<TValue>>?

I would think it's fairly straightforward to cast an IDictionary<TKey, IList<TValue>> object to an IDictionary<TKey, IEnumerable<TValue>> , but 我认为将IDictionary<TKey, IList<TValue>>对象转换为IDictionary<TKey, IEnumerable<TValue>>是相当简单的,但是

var val = (IDictionary<TKey, IEnumerable<TValue>>)Value;

throws a System.InvalidCastException , and 抛出System.InvalidCastException ,并且

var val = Value as IDictionary<TKey, IEnumerable<TValue>>;

makes val null. 使val null。 What is the proper way to cast this? 强制执行此操作的正确方法是什么?

I would think it's fairly straightforward to cast an IDictionary<TKey, IList<TValue>> object to an IDictionary<TKey, IEnumerable<TValue>> 我认为将IDictionary<TKey, IList<TValue>>对象转换为IDictionary<TKey, IEnumerable<TValue>>是相当简单的

Absolutely not. 绝对不。 It wouldn't be type-safe. 它不是类型安全的。 Here's an example of why not: 这是为什么不的示例:

// 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"];

As you can see, that's going to cause problems - we'd be trying to get a LinkedList<int> out when we expect all the values to implement IList<int> . 如您所见,这将导致问题-当我们期望所有值都实现IList<int>时,我们将尝试获取LinkedList<int> IList<int> The point of generics is to be type-safe - so which line would you expect to fail? 泛型的要点是类型安全的-那么您期望哪一行失败? The first, third and fourth lines look pretty clearly valid to me - so the second one is the only one which can fail to compile, and it does... 第一,第三和第四行对我来说显然很有效-因此第二行是唯一无法编译的行,并且确实可以...

Now in some cases, it can be done safely. 现在在某些情况下,可以安全地完成此操作。 For example, you can convert (in C# 4) from IEnumerable<string> to IEnumerable<object> because IEnumerable<T> only uses T in "output" positions. 例如,可以将IEnumerable<string>IEnumerable<object> (在C#4中),因为IEnumerable<T>仅在“输出”位置使用T

See MSDN for more details. 有关更多详细信息,请参见MSDN

EDIT: Just to clarify - it's easy to create a new dictionary with a copy of the existing key/value pairs, eg using link: 编辑:只是要澄清-很容易使用现有键/值对的副本来创建字典,例如使用链接:

var copy = original.ToDictionary<TKey, IEnumerable<TValue>>(pair => pair.Key,
                                                            pair => pair.Value);

You just need to be aware that you now have two separate dictionaries. 您只需要知道您现在有两个单独的字典。

This may or may not help you, but I thought I'd throw it out as a supplement to Jon's answer. 这可能对您没有帮助,但我认为我会将它作为Jon回答的补充。

If all you need is the dictionary's values , without reference to their keys, you can do this: 如果您只需要字典的 ,而无需引用其键,则可以执行以下操作:

IDictionary<TKey, IList<TValue>> dictionary = Whatever();
var values = (IEnumerable<IEnumerable<TValue>>)dictionary.Values;

For this to work, you must be using C# 4.0 or later, and TValue must be constrained to be a reference type. 为此,必须使用C#4.0或更高版本,并且TValue必须限制为引用类型。 Here's the code, slightly refactored, and with comments to explain: 这是经过稍微重构的代码,并带有注释来解释:

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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何转换IDictionary <TKey, List<TValue> &gt;到IDictionary <TKey, IEnumerable<TValue> &gt;? - How to convert IDictionary<TKey, List<TValue> > to IDictionary<TKey, IEnumerable<TValue> >? 推荐的转换IGrouping的方法 <TKey, TValue> 到IDictionary <TKey, IEnumerable<TValue> &gt; - Recommended way to convert IGrouping<TKey, TValue> to IDictionary<TKey, IEnumerable<TValue>> ObservableDictionary类 <TKey, TValue> :IDictionary <TKey, TValue> 作为DataContract - class ObservableDictionary<TKey, TValue> : IDictionary<TKey, TValue> as DataContract 为什么IDictionary <TKey,TValue>扩展ICollection <KeyValuePair <TKey,TValue >>? - Why does IDictionary<TKey, TValue> extend ICollection<KeyValuePair<TKey, TValue>>? 为什么要向上转换IDictionary <TKey, TValue> 到IEnumerable <object> 失败? - Why does upcasting IDictionary<TKey, TValue> to IEnumerable<object> fail? 为什么IDictionary <TKey,TValue>实现了ICollection和IEnumerable - Why IDictionary<TKey, TValue> implements both ICollection and IEnumerable 转换iDictionary <TKey,TValue> 进入IDictionary <TSomeProperty, ICollection<TValue> &gt; - Convert iDictionary<TKey,TValue> into IDictionary<TSomeProperty, ICollection<TValue>> 为什么反射器不显示 IDictionary<TKey, TValue> 实现 IEnumerable<T> ? - Why does the reflector not show that IDictionary<TKey, TValue> implements IEnumerable<T>? IDictionary <TKey,TValue>替换值的实现和合同 - IDictionary<TKey, TValue> implementation and contract for replacing values 当方法具有IDictionary和IDictionary的重载时的不明确调用<TKey, TValue> - Ambiguous call when a method has overloads for IDictionary and IDictionary<TKey, TValue>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM