显式强制转换存在,但似乎不适用于Dictionary <int,string []>到IDictionary <int,IEnumerable <string >>

Waf*_*fle 2 c#

使用隐式转换编写代码会生成CS0266.

Dictionary<Int32, string[]> d1 = new Dictionary<int, string[]>();
IDictionary<int, IEnumerable<string>> ide1 = d1; // CS0266
Run Code Online (Sandbox Code Playgroud)

显式强制转换存在的提示表明显式强制转换可以解决问题.

IDictionary<int, IEnumerable<string>> ide1 = (IDictionary<int, IEnumerable<string>>)d1; // No error, but throws an exception
Run Code Online (Sandbox Code Playgroud)

有没有办法让这个演员表演?它会为工作string[][]IEnumerable<IEnumerable<string>>

namespace Quickie
{
    class QuickieArray
    {
        private static void TestCastDictionaryWithArrayValue()
        {
            Console.WriteLine();
            Console.WriteLine("===TestCastDictionaryWithArrayValue===");
            Dictionary<Int32, string[]> d1 = new Dictionary<int, string[]>();
            d1[1] = new string[]{"foo"};
            IDictionary<int, string[]> id1 = d1;
            Console.WriteLine("id1 is null: {0}", id1 == null);
            IDictionary<int, IEnumerable<string>> ide1 = id1 as IDictionary<int, IEnumerable<string>>;
            IDictionary<int, IEnumerator<string>> iden1 = id1 as IDictionary<int, IEnumerator<string>>;
            Console.WriteLine("ide1 is null: {0}", ide1 == null);
            Console.WriteLine("iden1 is null: {0}", iden1 == null);

            Console.WriteLine();
        }
        internal static void Test()
        {
            Console.WriteLine();
            Console.WriteLine("=QuickieArray=");
            TestCastDictionaryWithArrayValue();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

=== TestCastDictionaryWithArrayValue ===
id1为null:False
ide1为null:True
iden1为null:True

Ada*_*ras 7

这是一个经典的协方差/逆转问题.我要告诉你一个简单的例子来证明为什么Dictionary<Int32, string[]>不是一个IDictionary<int, IEnumerable<string>>不能强制转换为一个.

让我们假装有问题的演员有效并且这段代码编译:

Dictionary<int, string[]> arrayDictionary = new Dictionary<int, string[]>();
IDictionary<int, IEnumerable<string>> enumerableDictionary = arrayDictionary;
Run Code Online (Sandbox Code Playgroud)

现在,我们有一个对象.它显然属于类型Dictionary<int, string[]>.我们有两个引用,一个是类型Dictionary<int, string[]>,一个是类型IDictionary<int, IEnumerable<string>>.

如果遵循此代码会发生什么?

List<string> stringList = new List<string>();
enumerableDictionary.Add(0, stringList);
Run Code Online (Sandbox Code Playgroud)

如果我们可以Dictionary<int, string[]>按照您想要的方式进行转换,上面的代码片段将成功编译...

......然后在运行时爆炸.为什么?因为List<string> 不是一个string[].

所述enumerableDictionaryAdd方法接受任何IEnumerable<string>,但实际已创建对象(Dictionary<int, string[]>)具有一个方法接受string[].

这就是为什么Dictionary<Int32, string[]>不是一个IDictionary<int, IEnumerable<string>>不能强制转换为一个.


D S*_*ley 6

不,没有演员,也不应该.想象一下:

        Dictionary<Int32, string[]> d1 = new Dictionary<int, string[]>();
        IDictionary<int, IEnumerable<string>> ide1 = d1; 
        ide1.Add(99,new List<string>());
Run Code Online (Sandbox Code Playgroud)

虽然第三行是完全可以接受的IDictionary<int, IEnumerable<string>>,但它是不可接受的IDictionary<int, string[]>.