c # ошибка приведения (значение infinte .... что?) - PullRequest
5 голосов
/ 08 декабря 2011

Возможно, что-то я пропускаю, но эта проблема меня сильно раздражает. Я пытаюсь получить значение из набора данных, а затем использовать его, чтобы сделать некоторые вычисления. в наборе данных он рассматривается как объект, поэтому мне нужно привести его к типу int или double. По какой-то причине я получаю глупую ошибку, которая действует мне на нервы. вот код.

private void SpendsAnalysis()
    {
        float tempQty = 0;
        float tempPrice = 0;
        double tempTot = 0;
        double total = 0;

        foreach (DataGridViewRow row in dataGridView1.Rows)
        {
            tempQty = (float)row.Cells["Qty"].Value;
            tempPrice = (float)row.Cells["Unit"].Value;

            tempTot = tempQty * tempPrice;
            total += tempTot;
        }

        textBox7.Text = total.ToString();
    }

Брошено: "Указанное приведение неверно (System.InvalidCastException) при приведении формы число должно быть меньше, чем inifnite. Это досадная ошибка, которую я получаю. Теперь я получаю данные из моего набора данных, который получает данные из хранимой процедуры. Я считаю, что тип поля "Кол-во" - это валюта (а почему кол-во валюты, ха-ха, а не мои таблицы!). в моем представлении таблицы данных это выглядит как 1.000, это из-за преобразования типов? как бы я исправить это? Большое спасибо заранее!

Ответы [ 2 ]

9 голосов
/ 08 декабря 2011

Приведение типов должно быть успешным, и, к сожалению, приведение непосредственно из 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, вы фактически распаковываете в штучной упаковке значение, и вам сначала нужно распаковать фактическое базовое значение в его правильный тип, прежде чем вы сможете преобразовать его в другой тип.
3 голосов
/ 08 декабря 2011

Лассе ответ правильный. Для получения более подробной информации о том, почему вы не можете распаковать T на что-либо, кроме T или обнуляемого T, см. Мою статью на эту тему:

http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...