嵌套接口:将IDictionary <TKey,IList <TValue >>转换为IDictionary <TKey,IEnumerable <TValue >>?

Jer*_*acs 2 c# generics casting interface

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

var val = (IDictionary<TKey, IEnumerable<TValue>>)Value;
Run Code Online (Sandbox Code Playgroud)

抛出一个System.InvalidCastException,和

var val = Value as IDictionary<TKey, IEnumerable<TValue>>;
Run Code Online (Sandbox Code Playgroud)

使valnull.投这个的正确方法是什么?

Jon*_*eet 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"];
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这将导致问题 - LinkedList<int>当我们期望所有值实现时,我们会尝试解决问题IList<int>.泛型的要点是类型安全 - 那么你期望失败的那条线?第一行,第三行和第四行对我来说看起来非常有效 - 所以第二行是唯一一个无法编译的行,它确实......

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

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

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

var copy = original.ToDictionary<TKey, IEnumerable<TValue>>(pair => pair.Key,
                                                            pair => pair.Value);
Run Code Online (Sandbox Code Playgroud)

您只需要知道您现在有两个单独的词典.