Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# cast error (infinte value....what?)

Prob something im overlooking but this problem has annoyed me greatly. im trying to get a value from a dataset and then use it to do some calculations. in the dataset its seen as an object, so i need to cast it to an int or double. For some reason im getting a stupid error thats getting on my nerves. heres the code.

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();
    }

Thrown: "Specified cast is not valid." (System.InvalidCastException) when casting form a number, must be less than inifnite. This is the annoying error im getting. now i get the data from my dataset, which gets its data from a stored procedure. I believe the "Qty" field type is currency(yeh, why is qty currency haha, not my tables!). in my datagrid view it looks like 1.000, is this due to a type conversion? how would i rectify this? Many Thanks in Advance!

like image 834
lemunk Avatar asked Dec 08 '11 08:12

lemunk


1 Answers

A type cast has to succeed, and unfortunately, casting directly from an object to a different type than the underlying object is not going to work, even if casting from a decimal (the .NET type for currency) to a float would normally work.

If the type in the database is currency, I would try this:

= (float)(decimal)row.Cells["Qty"].Value;

or, you can use this:

= Convert.ToSingle(row.Cells["Qty"].Value);

which will take a look at the actual value and figure out the right type of conversion to perform.

To answer your comment, the above expression involves two distinct conversions:

  • An unboxing conversion from object to a value-type, in this case to a decimal
  • An explicit conversion from decimal to float

The first, the unboxing conversion, is documented in the C# language specification section 4.3.2 (this is the C# 4.0 specification):

An unboxing operation to a non-nullable-value-type consists of first checking that the object instance is a boxed value of the given non-nullable-value-type, and then copying the value out of the instance.

(my emphasis)

I also have the annotated version of the specification, and Eric Lippert summarizes this as:

Although it is legal to convert an unboxed int to an unboxed double, it is not legal to convert a boxed int to an unboxed double—only to an unboxed int.

The second, the explicit conversion, is documented in the C# language specification section 6.2.1:

6.2.1 Explicit Numeric Conversions
The explicit numeric conversions are the conversions from a numeric-type to another numeric-type for which an implicit numeric conversion (§6.1.2) does not already exist:
...
From decimal to sbyte, byte, short, ushort, int, uint, long, ulong, char, float, or double.

(again, my emphasis)

To summarize:

  • When "casting" from an object to a value-type, you're actually unboxing the boxed value, and you first have to unbox the actual underlying value into its correct type, before you can convert it to a different type.
like image 199
Lasse V. Karlsen Avatar answered Sep 20 '22 10:09

Lasse V. Karlsen