10

所以我一直认为 c# 中的转换和转换基本上是同一件事:从一种数据类型转换为另一种数据类型的两种不同方式。显然这是不正确的,因为它们通常会输出不同的结果。

Convert.ToInt32(1.6)     //outputs 2
(Int32)1.6               //outputs 1


(DateTime)("10/29/2013")          //won't compile - cannot convert type 'string' to type 'system.date.time'
Convert.ToDateTime("10/29/2013")  //outputs 10/29/2013 12:00:00 AM
  • 我的问题是两者之间的主要区别是什么,为什么它们会返回不同的结果?
  • 什么是“适当”的时间来使用一个而不是另一个?

就我个人而言,我发现自己使用这种Convert.To方法,因为这对我来说似乎更干净。我知道它也会抛出System.InvalidCastException. 任何人都可以提供一个简单的解释吗?

4

3 回答 3

5

您可以在两种情况下使用 cast:

在所有其他情况下,您应该使用 Convert 或其他自定义转换方法(例如 DateTime.Parse)。

为什么他们返回不同的结果?

因为执行了不同的代码。Convert.ToInt32(double value)轮换结果:

int num = (int) value;
double num2 = value - num;
if ((num2 > 0.5) || ((num2 == 0.5) && ((num & 1) != 0)))    
    num++;

return num;
于 2013-10-29T15:50:57.893 回答
1

在您的转换中,该Convert.ToInt32方法对其返回值使用以下规则

值,四舍五入到最接近的 32 位有符号整数。如果 value 在两个整数的中间,则返回偶数;即4.5转换为4,5.5转换为6。

但是显式转换的规则是不同的

当您将十进制值转换为整数类型时,该值会朝零舍入到最接近的整数值。如果生成的整数值超出目标类型的范围,则会引发 OverflowException。

如果您希望强制转换的操作与Convert.ToInt32[或希望指定舍入的工作方式] 相同,那么您应该使用Math.Round带有强制转换的方法,如下所示。

(int)Math.Round(1.6) //outputs 2

还有其他方法签名允许您指定如何舍入。

至于何时应该使用强制转换和转换,您应该尽可能使用显式强制转换,意识到当从更精确的类型转换为不太精确的类型并适当处理它并在不期望数据时进行转换时,您将失去精度以可以转换的格式。 可能时意味着存在显式转换(包括隐式转换)时。预定义的转换可以在规范的第 6 节中找到

(T)E 形式的强制转换表达式,其中 T 是类型,E 是一元表达式,执行将 E 的值显式转换(第 6.2 节)到类型 T。如果不存在从类型的显式转换从 E 到 T,发生编译时错误。否则,结果是显式转换产生的值。

于 2013-10-29T16:03:32.537 回答
0

没有适用于所有情况的快速规则。你只需要知道每一个做什么,然后选择最适合你的场景的一个。就像您自己指出的那样,Convert 和 cast 可以产生不同的结果。原因是 Convert 和 cast 可以有完全不同的实现。

public static explicit operator MyStructA(MyStructB b)  
{
    MyStructA a = convert.ToMyStructA(b); 
    //I could do this so that convert and cast return the same but I don't have to.

    return a;
}
于 2013-10-29T16:12:59.047 回答