Подтвердить что ты не робот

Почему это отбрасывается от 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 принимает объект, поэтому мы действительно удалили актерский состав из нашего кода, но я хотел бы получить объяснение относительно того, почему этот кастинг был неудачным на всякий случай, когда мы сталкиваемся с чем-то вроде этого в будущее.

4b9b3361

Ответ 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"]