为什么下一个示例会抛出System.ArrayTypeMismatchException?
New Int16(){4,5,6}.Cast(of UInt16).ToArray()
我希望这一行返回一个包含4,5和6的UInt16数组。
提前致谢。
答案 0 :(得分:7)
这是IMO Cast
或ToArray
中的错误。这个答案中的代码是在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
仅适用于拆箱操作和参考类型转换。
答案 1 :(得分:5)