为什么var被解析为Double而不是Long

本文关键字:Long Double var 为什么 | 更新日期: 2023-09-27 18:24:21

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

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

为什么var被解析为Double而不是Long

有一个从Int64Double的隐式转换,但没有其他方式(由于可能在该方向上失去精度)。

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

您可以将long隐式转换为double

不能将double隐式转换为long

因此,C#编译器决定变量类型的唯一可能性是double

请参见隐式数值转换表。

因为编译器需要推断出一个可以同时包含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());
}

C#编译器根据三进制的两个返回类型之间的公约数推断类型。Int64可以隐式转换为Double。事实并非如此。

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

这是?:运算符的工作。它应该将所有结果强制转换为一种类型。

p.S.你知道的+操作员的类似行为:

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

附言:要得到你想要的东西,你应该使用object:

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

p.p.p.S.另一种选择是:

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

要定义为Int,请使用

#define asInt

我很惊讶没有人指出如果您知道该值将是合法的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());

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