2

我认为将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为空。投射这个的正确方法是什么?

4

2 回答 2

8

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

LinkedList<int>正如你所看到的,这会导致问题——当我们期望所有的值都能实现时,我们会试图摆脱困境IList<int>。泛型的重点是类型安全——那么你希望哪一行会失败?第一行、第三行和第四行对我来说显然很有效 - 所以第二行是唯一无法编译的行,它确实......

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

有关详细信息,请参阅MSDN 。

编辑:澄清一下 -使用现有键/值对的副本创建一个字典很容易,例如使用链接:

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

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

于 2012-05-01T15:03:51.407 回答
0

这可能会或可能不会帮助你,但我想我会把它作为对乔恩回答的补充。

如果您只需要字典的values,而不参考它们的键,您可以这样做:

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;
于 2012-05-12T00:46:11.143 回答