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

时间:2012-02-14 12:29:34

标签: 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());

6 个答案:

答案 0 :(得分:12)

存在从Int64Double的隐式转换,但不是另一种方式(由于该方向可能会失去精度)。

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

答案 1 :(得分:5)

您可以隐式地将long投射到double

您无法隐式地将double投射到long

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

请参阅Implicit Numeric Conversions Table

答案 2 :(得分: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());
}

答案 3 :(得分:1)

C#编译器从三元的两种返回类型之间的公分母推断出类型。 Int64可以隐式转换为Double。反之则并非如此。

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

答案 4 :(得分:0)

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

P.S。您知道+运营商的类似行为:

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

P.P.S。要拥有您想要的内容,您应该使用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());

定义asInt使用

#define asInt

答案 5 :(得分: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());

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