【问题标题】:Cast object containing int to float results in InvalidCastException将包含 int 的对象转换为 float 会导致 InvalidCastException
【发布时间】:2014-06-27 08:33:34
【问题描述】:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
    var fP18VaR = (float) (int)e.Values[0];
}

我来了

InvalidCastException - 指定的强制转换无效

为什么它不起作用?

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

【问题讨论】:

  • 什么 e.Values[0]Horse编辑所以它是6 666,00,十进制/双精度数还是string
  • 也许int 的转换已经失败?
  • e.Values[0].GetType()?
  • 我同意@UweKeim .. 我认为这些值与其他数据类型有关。
  • 这真的是 6[whitespace]666,00 吗?如果是这样,int 解析可能已经失败了

标签: c#


【解决方案1】:

您在这里遇到的问题是 C# 强制转换运算符在不同情况下的含义不同。

以你给出的这个例子为例:

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

C# 编译器会认为你在告诉它:“变量 num 指的是一个装箱的浮点数;请取消装箱并返回装箱后的值。”

您收到错误,因为它不是盒装浮点数,而是盒装 int。

问题在于 C# 对两个完全不相关的操作使用相同的语法:“拆箱”和“数字转换”。下面是一个强制转换表示数字转换的示例:

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

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

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

那么你如何得到你想要的结果呢?好吧,你需要做这两个操作:你需要拆箱 int 然后你需要把它转换成一个浮点数。所以你实际上需要两个演员表:

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

可怕吧?

在这里做你想做的最简单的方法是完全避免强制转换。只需这样做:

float fnum = Convert.ToSingle(num); 

如果可能的话,这会将类型强制为单精度浮点数。

【讨论】:

    【解决方案2】:

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

    (int)e.Values[0]
    

    成功,然后

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

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

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

    【讨论】:

      【解决方案3】:

      您的转换无效,因为 e.Values[0] 将装箱值作为对象返回,首先需要将其转换为正确的基础类型。要将基础值转换为浮点数,您需要先指定正确的类型。

      另外,如果 object 不是值类型,而是其他容器,或者例如,字符串 - 你需要先转换到这个容器,然后找到一种方法如何将它转换为浮点数。

      Eric Lipper 有一篇关于这个主题的优秀文章:Representation and Identity

      【讨论】:

        【解决方案4】:

        考虑改用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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多