C# 为什么var被解析为一个双精度变量而不是一个长变量?

C# 为什么var被解析为一个双精度变量而不是一个长变量?,c#,double,int64,C#,Double,Int64,在下面的代码中,我希望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的类型最终被推断为Dou

在下面的代码中,我希望
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。相反,情况并非如此


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

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

另外,您知道的
+
操作员的类似行为:

string a =  "1234";
var b = Int64.Parse(a) + Double.Parse(a) ;
Console.WriteLine(b.GetType());
p.p.S.要得到你想要的,你应该使用
对象

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());
定义新用途

#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());

换句话说,最好的解决方案可能不使用三元运算符,但这个问题并没有给出足够的背景知识。

我有点惊讶,即使是编译。我认为三元结构的双方都必须返回相同的类型,尽管我怀疑存在从long到double的隐式对话这就解释了,有道理。是否有任何方法可以在需要时创建Int64类型的变量
b
,并在需要时创建双精度变量(基于bool
asInt
)?当然,在if语句中初始化它不起作用,因为它的作用域被限制在该if语句中block@xbonez-不使用条件运算符。必须在运行时推断/确定类型。您可以使用
dynamic
.Hmm…谢谢。我将研究动态。我知道数学运算在双精度上比较慢,所以我希望在不需要的时候不要使用双精度。我将研究动态,但如果这不起作用,我想我会接受它。@xbonez:请注意
dynamic
本身就有运行时开销。如果要优化执行速度,最好使用
double
。@xbonez:使用dynamic可能比double慢数十万倍。记住,dynamic在运行时再次启动编译器,这就是dynamic的含义。如果您有一个场景,其中整数和双精度算术之间的差异(几纳秒)是相关的,那么您需要非常仔细地进行概要文件驱动的分析。你不能只看代码就知道它的哪些部分需要一个机器周期而不是四个机器周期。那么,我有没有办法做你已经做过的事情,还能够访问if-else范围之外的变量b?@xbonez,是的,但是你应该将
b
定义为type
object
object b完美…这就是我一直在寻找的东西<代码>对象
正是我所需要的。非常感谢。哦,等等……它不允许我对
对象
(>,等等)执行任何操作,除非我先将其转换为
Int64
Double
,这有点违背了目的,因为我直到运行时才知道类型。不幸的是,
对象
要求我将其强制转换为
Int64
double
,然后才能对其执行任何操作,这是不可能的,因为我在运行时之前不知道类型,然后尝试条件编译指令,
#如果
etcAlso,如果不依赖算术运算符,则可以使用泛型方法和/或类型。如果你是,那么你会做更多的把戏。