为什么IEnumerable的ToArray()扩展方法抛出ArrayTypeMismatchException?
问题描述:
为什么下一个示例抛出System.ArrayTypeMismatchException?为什么IEnumerable的ToArray()扩展方法抛出ArrayTypeMismatchException?
New Int16(){4,5,6}.Cast(of UInt16).ToArray()
我预计这一线返回一个包含预先4,5和6
感谢UINT16阵列。
答
这是Cast
或ToArray
一个bug,IMO。在这个答案中的代码是在C#中,但希望你可以看到它是关于:)
我相信Cast
首先试图看看是否一个简单的参考转换将工作 - 即它可以返回相同的参考返回。
例如:
String x = "hello";
IEnumerable<char> y = x.Cast<char>();
Console.WriteLine(object.ReferenceEquals(x, y)); // Prints true
不幸的是,它这样做使用CLR规则兼容性 - 在其下UInt16[]
和Int16[]
是兼容。导致这种情况的发生:
short[] array = new short[]{4, 5, 6};
IEnumerable<ushort> cast = array.Cast<ushort>();
Console.WriteLine(object.ReferenceEquals(array, cast)); // Prints True
不幸的是,如果你再尝试拨打ToArray()
,它不是高兴:
// Explicit type argument just for clarity
cast.ToArray<ushort>(); // Bang
ToArray
无疑会尝试做一些优化 - 这无法在这种特殊情况下,因为类型并不是它真正期望的那样。
我相信正确行为应该是为Cast
返回一个懒惰的迭代器,但为此以后执行失败。例如,如果您尝试从Int16
到Int32
,就会发生这种情况。
现在,回到真的想要做的事情:改用Select
来代替。 Cast
仅用于拆箱操作和参考类型转换。
答
谢谢,不幸的是我还没有关于LINQ的知识,你知道,我总是有更多的事情要做。无论如何,再次感谢。 – 2009-12-14 13:47:07