为什么下一个示例抛出System.ArrayTypeMismatchException?

New Int16(){4,5,6}.Cast(of UInt16).ToArray()

我希望这一行返回一个包含4,5和6的UInt16数组。

提前致谢。

最佳答案

这是IMO的CastToArray中的错误。此答案中的代码在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仅用于取消装箱操作和引用类型转换。

关于.net - 为什么此IEnumerable的ToArray()扩展方法抛出ArrayTypeMismatchException?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1900598/

10-12 17:22