gpt4 book ai didi

c# - 为什么将值转换为 IEnumerable 的行为会根据我初始化值的方式而有所不同?

转载 作者:太空狗 更新时间:2023-10-29 21:49:05 25 4
gpt4 key购买 nike

我有一些代码接受一个值(对象类型)并尝试将其转换为 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 的即时窗口中,如我所料返回 null,即使该值是使用集合初始值设定项生成的。

.Net fiddle reproducing the error here .

这是怎么回事?

最佳答案

我认为这是因为 C# 和 CLR 在处理 int 之间的转换方面存在不寻常的差异。和 uint ,如本 answer 中所述.首先请注意,此代码无法编译:

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不为空。这对于列表来说是不正确的 - 因此你的问题。

至于为什么 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直接检查一个数组中的元素类型是否与另一个数组中的元素类型兼容。

关于c# - 为什么将值转换为 IEnumerable<T> 的行为会根据我初始化值的方式而有所不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37553042/

25 4 0