为什么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());
有一个从Int64
到Double
的隐式转换,但没有其他方式(由于可能在该方向上失去精度)。
由于条件的两个"分支"都需要解析为相同的类型,因此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());
换句话说,最好的解决方案可能不使用三元运算符,但这个问题没有提供足够的上下文来了解。