Почему это отбрасывается от short to int fail?
У нас есть код, который архивирует данные из базы данных Microsoft Access в базу данных MS SQL Server. Предполагая, что у нас есть считыватель данных, уже заполненный из таблицы Access, и мы добавляем параметр в SqlCommand в процессе подготовки к вставке, у нас есть ошибка типа, которая терпит неудачу. Вот код:
oSqlServerDbCmd_ForInsert.Parameters.AddWithValue("@Duration",
(int) oReader["Duration"]);
Поле из oReader на самом деле является Integer Access, который является коротким на С#. Если мы кратко остановимся здесь, проблем нет. Однако, если мы применяем int, код генерирует InvalidCastException. Возможно, это неверно из документации MSDN:
"Существует предопределенное неявное преобразование от короткого к int, long, float, double или decimal".
... но похоже, что это должно работать (по моему рассуждению, если определено неявное преобразование, почему бы не явный тип не работал?). Я понимаю, что актер даже не нужен, потому что AddWithValue принимает объект, поэтому мы действительно удалили актерский состав из нашего кода, но я хотел бы получить объяснение относительно того, почему этот кастинг был неудачным на всякий случай, когда мы сталкиваемся с чем-то вроде этого в будущее.
Ответы
Ответ 1
У вас в руках есть экземпляр unboxing. В частности, при распаковке вы можете освобождать только тот тип значения, которое было первоначально вставлено в коробку; если этот тип есть A, и вы распаковываете его в B, не имеет значения, существует ли неявное преобразование из A в B (unboxing все равно будет неработать).
См. Eric Lippert классический пост в блоге по теме для объяснения.
Ответ 2
Вам нужно указать конкретный тип, поскольку вы распаковываете - проблема в том, что oReader["Duration"]
возвращает экземпляр object
:
short myShort = 42;
object o = myShort;
int myInt = (int)o; //fails
Это будет выполнено, если вы сначала вернетесь к первому, затем к int:
(int) (short) oReader["Duration"]