包含int到float的Cast对象导致InvalidCastException

时间:2014-06-27 08:33:34

标签: c#

protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
    var fP18VaR = (float) (int)e.Values[0];
}

我正在

  

InvalidCastException - 指定的强制转换无效

为什么不起作用?

e.Values [0]的值是:6 666,00

4 个答案:

答案 0 :(得分:19)

你遇到的问题是C#cast运算符在不同的情况下意味着不同的东西。

以你给出的这个例子:

object num = 10;
float fnum = (float)num;

C#编译器会认为你是这么说的:“变量num指的是一个盒装浮点数;请取消装箱并返回盒装值。”

你得到一个错误,因为它不是一个盒装浮点数,它是一个盒装的int。

问题在于C#对两个完全不相关的操作使用相同的语法:'unbox'和'numeric conversion'。以下是演员表示数字转换的示例:

int num = 10;
float fnum = (float)num;

几乎完全相同的代码,但这不会给你一个错误。这是因为C#编译器完全不同地对待它 - 这段代码意味着:“请执行数字转换,将存储在'num'中的整数转换为单精度浮点值。”

你怎么知道这两个完全无关的操作中哪一个会选择?这都是关于源和目标类型的。如果您要从“对象”转换为值类型,则始终将其视为unbox。如果您要从一种数字类型转换为另一种数字类型,则始终将其视为数字转换。

那么你如何得到你想要的结果呢?好吧,你需要做两个操作:你需要取消装入int然后你需要将它转换为浮点数。所以你实际上需要两个演员:

object num = 10;
float fnum = (float) (int)num; 

太可怕了?

在这里做你想做的最简单的方法是避免完全铸造。就这样做:

float fnum = Convert.ToSingle(num); 

如果可以这样做,那么将该类型强制转换为单精度浮点数。

答案 1 :(得分:2)

e.Values[0]的编译时类型为Object。因此,您需要进行转换或转换以获取float。如果

(int)e.Values[0]

成功,然后

(float) (int)e.Values[0]

会成功。因此,e.Values[0]无法转换为int

下一步是弄清楚e.Values[0]的运行时类型和值是什么,并尝试了解如何将其转换为数值。

答案 2 :(得分:1)

请考虑使用TryParse;下面稍微详细的示例,让您了解如何处理错误解析以及如何随后将可空浮点转换为常规浮点数:

protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
    float? temp;
    if (!float.TryParse(e.Values[0], out temp))
    {
        //code to handle problems parsing here
        throw new InvalidCastException("Invalid cast: '{0}' cannot be parsed to a float", e.Values[0]);
    }
    //if we reach here (we've not thrown an error above), `temp` is not null
    var fP18VaR = temp.Value;
}

注意:此功能考虑了当前的文化;因此,如果您正在使用多文化数据,则需要了解这些数字的格式。有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/3s27fasw(v=vs.110).aspx

答案 3 :(得分:0)

你的演员表是无效的,因为e.Values [0]将盒装值作为对象返回,首先需要强制转换为正确的底层类型。要将基础值转换为float,您需要首先指定正确的类型。

此外,如果object不是值类型,而是某个其他容器,或者例如string - 您需要首先转换为此容器,然后找到如何将其转换为float的方法。

Eric Lipper撰写了关于此主题的优秀文章:Representation and Identity