显式强制转换存在,但似乎不适用于Dictionary到字典
本文关键字:int string IEnumerabl 字典 Dictionary 不适用 转换 存在 适用于 | 更新日期: 2023-09-27 18:17:57
使用隐式强制转换编写代码生成CS0266。
Dictionary<Int32, string[]> d1 = new Dictionary<int, string[]>();
IDictionary<int, IEnumerable<string>> ide1 = d1; // CS0266
存在显式强制转换的提示表明显式强制转换可以解决这个问题。
IDictionary<int, IEnumerable<string>> ide1 = (IDictionary<int, IEnumerable<string>>)d1; // No error, but throws an exception
有办法让这个cast吗?对于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();
}
}
}
输出: = = = TestCastDictionaryWithArrayValue = = =
id1是null: False
ide1是null: True
iden1 is null: True
这是一个经典的协方差/逆变问题。我将向您展示一个简化的示例来证明为什么Dictionary<Int32, string[]>
是而不是, IDictionary<int, IEnumerable<string>>
和不能将转换为一个。
让我们暂时假设所讨论的强制转换有效,并且编译以下代码:
Dictionary<int, string[]> arrayDictionary = new Dictionary<int, string[]>();
IDictionary<int, IEnumerable<string>> enumerableDictionary = arrayDictionary;
现在,我们有一个对象。很明显是Dictionary<int, string[]>
类型的。我们有两个对它的引用,一个是Dictionary<int, string[]>
类型,另一个是IDictionary<int, IEnumerable<string>>
类型。
如果后面跟着这段代码会发生什么?
List<string> stringList = new List<string>();
enumerableDictionary.Add(0, stringList);
如果我们可以按照您想要的方式转换Dictionary<int, string[]>
,那么上面的代码段将成功编译…
…然后在运行时爆炸。为什么?因为List<string>
不是 string[]
.
enumerableDictionary
的Add
方法接受任何IEnumerable<string>
,但是创建的真实的对象(Dictionary<int, string[]>
)有一个方法,只有接受string[]
。
这就是为什么Dictionary<Int32, string[]>
是而不是, IDictionary<int, IEnumerable<string>>
和不能强制转换为一个
没有,也不应该有。想象下面的内容:
Dictionary<Int32, string[]> d1 = new Dictionary<int, string[]>();
IDictionary<int, IEnumerable<string>> ide1 = d1;
ide1.Add(99,new List<string>());
虽然第三行对于IDictionary<int, IEnumerable<string>>
来说是完全可以接受的,但是对于IDictionary<int, string[]>
来说是不可接受的。
正如@adam-maras和@d-stanley所说,这是一个协方差问题。因此,尽可能使用接口。例如,使用IDictionary<Int32, IEnumerable<string>>
作为派生较少的类型来保存用派生较多的类型实例化的数据:
using System;
using System.Collections.Generic;
namespace Quickie
{
class QuickieArray
{
private static void TestCastIDictionaryWithArrayValue()
{
Console.WriteLine();
Console.WriteLine("===TestCastIDictionaryWithArrayValue===");
IDictionary<int, IEnumerable<string>> d1 = new Dictionary<int, IEnumerable<string>>();
d1[1] = new string[] { "foo" };
IDictionary<int, IEnumerable<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();
TestCastIDictionaryWithArrayValue();
}
}
}
至于显式强制转换存在吗?不,没有。
像这样的东西也可以工作就像一个例子在我的例子中,我从逗号分隔字段读取
var intFileCount = 0;
Dictionary<int, string[]> dctListRecords = null;
//initialize a capacity if you want
dctListRecords = new Dictionary<int, string[]>(strLinesStockRecord.Count());
foreach (string strLineSplit in strLinesStockRecord)
{
lstSplitList2 = strLineSplit.Split(chrCOMMA_SEP).ToList();
dctListRecords.Add(intFileCount, lstSplitList2.ToArray());
//this allows you to use the string value inside of string[]
lstSplitList2.Clear();
intFileCount++;
}
本文关键字:int string IEnumerabl 字典 Dictionary 不适用 转换 存在 适用于 | 更新日期: 2023-09-27 18:17:57
使用隐式强制转换编写代码生成CS0266。
Dictionary<Int32, string[]> d1 = new Dictionary<int, string[]>();
IDictionary<int, IEnumerable<string>> ide1 = d1; // CS0266
存在显式强制转换的提示表明显式强制转换可以解决这个问题。
IDictionary<int, IEnumerable<string>> ide1 = (IDictionary<int, IEnumerable<string>>)d1; // No error, but throws an exception
有办法让这个cast吗?对于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();
}
}
}
输出:= = = TestCastDictionaryWithArrayValue = = =
id1是null: False
ide1是null: True
iden1 is null: True
这是一个经典的协方差/逆变问题。我将向您展示一个简化的示例来证明为什么Dictionary<Int32, string[]>
是而不是, IDictionary<int, IEnumerable<string>>
和不能将转换为一个。
让我们暂时假设所讨论的强制转换有效,并且编译以下代码:
Dictionary<int, string[]> arrayDictionary = new Dictionary<int, string[]>();
IDictionary<int, IEnumerable<string>> enumerableDictionary = arrayDictionary;
现在,我们有一个对象。很明显是Dictionary<int, string[]>
类型的。我们有两个对它的引用,一个是Dictionary<int, string[]>
类型,另一个是IDictionary<int, IEnumerable<string>>
类型。
如果后面跟着这段代码会发生什么?
List<string> stringList = new List<string>();
enumerableDictionary.Add(0, stringList);
如果我们可以按照您想要的方式转换Dictionary<int, string[]>
,那么上面的代码段将成功编译…
…然后在运行时爆炸。为什么?因为List<string>
不是 string[]
.
enumerableDictionary
的Add
方法接受任何IEnumerable<string>
,但是创建的真实的对象(Dictionary<int, string[]>
)有一个方法,只有接受string[]
。
这就是为什么Dictionary<Int32, string[]>
是而不是, IDictionary<int, IEnumerable<string>>
和不能强制转换为一个
没有,也不应该有。想象下面的内容:
Dictionary<Int32, string[]> d1 = new Dictionary<int, string[]>();
IDictionary<int, IEnumerable<string>> ide1 = d1;
ide1.Add(99,new List<string>());
虽然第三行对于IDictionary<int, IEnumerable<string>>
来说是完全可以接受的,但是对于IDictionary<int, string[]>
来说是不可接受的。
正如@adam-maras和@d-stanley所说,这是一个协方差问题。因此,尽可能使用接口。例如,使用IDictionary<Int32, IEnumerable<string>>
作为派生较少的类型来保存用派生较多的类型实例化的数据:
using System;
using System.Collections.Generic;
namespace Quickie
{
class QuickieArray
{
private static void TestCastIDictionaryWithArrayValue()
{
Console.WriteLine();
Console.WriteLine("===TestCastIDictionaryWithArrayValue===");
IDictionary<int, IEnumerable<string>> d1 = new Dictionary<int, IEnumerable<string>>();
d1[1] = new string[] { "foo" };
IDictionary<int, IEnumerable<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();
TestCastIDictionaryWithArrayValue();
}
}
}
至于显式强制转换存在吗?不,没有。
像这样的东西也可以工作就像一个例子在我的例子中,我从逗号分隔字段读取
var intFileCount = 0;
Dictionary<int, string[]> dctListRecords = null;
//initialize a capacity if you want
dctListRecords = new Dictionary<int, string[]>(strLinesStockRecord.Count());
foreach (string strLineSplit in strLinesStockRecord)
{
lstSplitList2 = strLineSplit.Split(chrCOMMA_SEP).ToList();
dctListRecords.Add(intFileCount, lstSplitList2.ToArray());
//this allows you to use the string value inside of string[]
lstSplitList2.Clear();
intFileCount++;
}