爲什麼下一個示例拋出System.ArrayTypeMismatchException?爲什麼IEnumerable的ToArray()擴展方法拋出ArrayTypeMismatchException?
New Int16(){4,5,6}.Cast(of UInt16).ToArray()
我預計這一線返回一個包含預先4,5和6
感謝UINT16陣列。
爲什麼下一個示例拋出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