Почему этот ToArray () дополнительный метод IEnumerable бросает ArrayTypeMismatchException?

Это то, что я считаю сгенерированными файлами, и как таковой, я никогда не размещаю их при управлении версиями. Они могут отличаться с машины на машину и разработчика разработчику, например, когда людям установили различные плагины Eclipse.

Вместо этого я использую инструмент сборки (Знаток), который может генерировать начальные версии этих файлов, когда Вы делаете новый контроль.

5
задан Ignacio Soler Garcia 14 December 2009 в 12:15
поделиться

2 ответа

Это ошибка в Cast или ToArray, 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, несомненно, пытается провести некоторую оптимизацию - что в данном случае не удается, так как тип не тот, что он на самом деле ожидает.

Я считаю, что поведение correct должно быть таким, чтобы Cast возвращал ленивый итератор, но чтобы он не сработал, когда он выполнится позже. Вот что произойдет, если, например, попытаться перейти от Int16 к Int32.

Теперь, чтобы вернуться к тому, что вы на самом деле хотите сделать: используйте вместо этого вызов Select. Cast предназначен только для операций распаковки и приведения типов ссылок.

.
7
ответ дан 13 December 2019 в 05:36
поделиться

Потому что Int16 и UInt16 относятся к разным типам. Вы можете попробовать следующее:

New Int16() {4, 5, 6}.Select(Function(x) CType(x, UInt16)).ToArray()
5
ответ дан 13 December 2019 в 05:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: