我认为将IDictionary<TKey, IList<TValue>>对象强制转换为IDictionary<TKey, IEnumerable<TValue>>相当简单,但是
var val = (IDictionary<TKey, IEnumerable<TValue>>)Value;抛出System.InvalidCastException,然后
var val = Value as IDictionary<TKey, IEnumerable<TValue>>;使val为空。什么是正确的投射方式?
发布于 2012-05-01 23:03:51
我认为将
IDictionary<TKey, IList<TValue>>对象转换为IDictionary<TKey, IEnumerable<TValue>>是相当简单的
绝对不是。它就不是类型安全的。这里有一个为什么不是这样的例子:
// 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:
var copy = original.ToDictionary<TKey, IEnumerable<TValue>>(pair => pair.Key,
pair => pair.Value);您只需要知道,您现在有两个独立的字典。
发布于 2012-05-12 08:46:11
这可能对你有帮助,也可能没有帮助,但我想我应该把它作为Jon答案的补充。
如果您只需要字典的值,而不引用它们的键,则可以这样做:
IDictionary<TKey, IList<TValue>> dictionary = Whatever();
var values = (IEnumerable<IEnumerable<TValue>>)dictionary.Values;要使其起作用,您必须使用C# 4.0或更高版本,并且必须将TValue约束为引用类型。下面是代码,稍微进行了重构,并带有注释进行解释:
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;https://stackoverflow.com/questions/10399568
复制相似问题