Приведение типов должно быть успешным, и, к сожалению, приведение непосредственно из object
к типу, отличному от базового объекта, работать не будет, даже если приведение из decimal
(тип .NET для currency
) до float
нормально бы работало.
Если тип в базе данных currency
, я бы попробовал это:
= (float)(decimal)row.Cells["Qty"].Value;
или вы можете использовать это :
= Convert.ToSingle(row.Cells["Qty"].Value);
, которое взглянет на фактическое значение и определит правильный тип преобразования для выполнения.
Чтобы ответить на ваш комментарий, вышеприведенное выражение включает в себя дваразличные преобразования:
- преобразование без распаковки из
object
в тип значения, в данном случае в decimal
- явное преобразование из
decimal
в float
Первое, преобразование без распаковки, задокументировано в разделе 4.3.2 спецификации языка C # (это спецификация C # 4.0 ):
Операция распаковки для типа с ненулевым значением состоит из первой проверки, чтоЭкземпляр объекта представляет собой упакованное значение с заданным типом ненулевого значения , а затем копирует значение из экземпляра.
(мой акцент)
У меня также есть аннотированная версия спецификации, и Эрик Липперт резюмирует это следующим образом:
Несмотря на то, что преобразование unboxed int в unboxed double допустимо, это недопустимопреобразовать упакованный int в незагруженный double - только в unboxed int.
Второе явное преобразование задокументировано в разделе 6.2.1 спецификации языка C #:
6.2.1 Явные числовые преобразования
Явные числовые преобразования - это преобразования из числового типа в другой числовой тип, для которого неявное числовое преобразование (§6.1.2) еще не существует:
...
Из десятичное для sbyte, byte, short, ushort, int, uint, long, ulong, char, float или double.
(опять же, мой акцент)
Подводя итог:
- При "касте" из
object
вvalue-type, вы фактически распаковываете в штучной упаковке значение, и вам сначала нужно распаковать фактическое базовое значение в его правильный тип, прежде чем вы сможете преобразовать его в другой тип.