4

在下面的代码中,我希望var得到解析为Int64,但它被解析为double. 为什么会这样?

string a =  "1234";
bool asInt = true;
var b = (asInt) ? Int64.Parse(a) : Double.Parse(a) ;
Console.WriteLine(b.GetType());
4

6 回答 6

12

存在从Int64to的隐式转换,Double但不是其他方式(由于在该方向上可能会丢失精度)。

由于条件的两个“分支”都需要解析为相同的类型,因此类型b最终被推断为Double.

于 2012-02-14T12:31:55.400 回答
5

您可以将 a 隐式long转换为 a double

您不能将 a 隐式double转换为 along

所以 C# 编译器决定你的变量类型的唯一可能性是double.

请参阅隐式数字转换表

于 2012-02-14T12:32:15.127 回答
4

因为编译器需要推断出一种类型,该类型可以同时保存两者的值,Int64.Parse(a)并且Double.Parse(a)不需要显式强制转换。如果long是推断的,则表达式的其他部分将丢失精度。

如果需要区分类型,则必须声明两个变量并重写代码:

if (asInt)
{
    var b = Int64.Parse(a); // will infer a `long`
    Console.WriteLine(b.GetType());
}
else
{
    var b = Double.Parse(a); // will infer a `double`
    Console.WriteLine(b.GetType());
}
于 2012-02-14T12:33:53.953 回答
1

C# 编译器从三元的两个返回类型之间的公分母推断类型。Int64 可以隐式转换为 Double。反之则不然。

请注意,您的代码示例中的布尔值状态与推断类型无关。

于 2012-02-14T12:35:47.947 回答
0

我很惊讶没有人指出,如果您知道该值将是合法 long 值,则可以通过显式强制转换来更改编译器的行为,然后使用 long.

这可能有帮助,也可能没有帮助,具体取决于确定 的值的条件asInt,以及您打算如何处理表达式的结果。这是一个例子:

string a =  "1234.56"; 
bool asDouble = a.Contains("."); 
var b = asDouble ? (long)Double.Parse(a) : Int64.Parse(a);
Console.WriteLine(b.GetType());

事实上,在这个例子中,你不需要条件运算符;这也可以:

string a =  "1234.56"; 
var b = (long)Double.Parse(a);
Console.WriteLine(b.GetType());

换句话说,最好的解决方案可能不会使用三元运算符,但问题并没有提供足够的上下文来了解。

于 2012-02-14T15:43:49.017 回答
0

这是?:操作员的工作。它应该将所有结果转换为一种类型。

+PS你知道的运算符的类似行为:

string a =  "1234";
var b = Int64.Parse(a) + Double.Parse(a) ;
Console.WriteLine(b.GetType());

PPS 要拥有你想要的东西,你应该使用object

string a =  "1234";
bool asInt = true;
object b;
if(asInt) b=Int64.Parse(a); else b=Double.Parse(a);
Console.WriteLine(b.GetType());

PPPS 另一种选择是:

        string a = "1234";
#if asInt
        Int64 b = Int64.Parse(a);
#else
        Double b = Double.Parse(a);
#endif
        Console.WriteLine(b.GetType());

定义 asInt 使用

#define asInt
于 2012-02-14T12:36:03.233 回答