我有一些代码需要一个值(类型对象),并尝试将其强制转换为int和uint的IEnumerable,如下所示:
var idList = value as IEnumerable<int>;
var uintList = value as IEnumerable<uint>;
以这种方式初始化值时:
uint number = 1;
object value = new []{ number };
idList和uintList都具有值,但是调用idList.ToList()会导致ArrayTypeMismatchException
。但是,当使用生成值时new List<uint>{ number }
,idList为预期的空值。
此外,var idList = value as IEnumerable<int>;
在VS 2015中立即窗口中调用会返回空值,正如我期望的那样,即使使用集合初始化程序生成了该值也是如此。
这里发生了什么?
我认为这是因为C#和CLR处理int
和之间的转换之间存在异常的区别uint
,如本答案所述。首先请注意,该代码不会编译:
uint[] a1 = new[] { 1u };
var a2 = (int[])a1;
因为C#不相信存在强制转换。但是,如果您采用这种方式:
uint[] a1 = new[] { 1u };
var a2 = (int[]) (object) a1;
运行时将决定此强制转换是否有效,并且它(CLR)会以不同的方式考虑,并允许从uint[]
到int[]
(反之亦然)强制转换,如我所链接的答案中所述。
但相同的是不是真正的List<int>
和List<uint>
-它们不是由CLR一种特殊的方式,因此不能相互之间施放治疗。
因此,在您的情况下,uint[]
可以强制转换为int[]
并int[]
实现IEnumerable<int>
,因此您idList
不为null。对于列表而言,这不是正确的-因此是您的问题。
至于为什么ToList在第一种情况下会失败,那是因为在内部它会执行以下操作:
uint[] a1 = new[] { 1u };
var a2 = (int[]) (object) a1;
// ToList copies contents to new array
int[] copy = new int[a2.Length];
Array.Copy(a2, copy, a2.Length);
并Array.Copy
直接检查一个数组中的元素类型是否与另一数组中的元素类型兼容。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句