在以下代码中,我希望var
可以解析为Int64
,但会解析为double
。为什么会这样?
string a = "1234";
bool asInt = true;
var b = (asInt) ? Int64.Parse(a) : Double.Parse(a) ;
Console.WriteLine(b.GetType());
答案 0 :(得分:12)
存在从Int64
到Double
的隐式转换,但不是另一种方式(由于该方向可能会失去精度)。
由于条件的两个“分支”都需要解析为相同类型,因此b
的类型最终会被推断为Double
。
答案 1 :(得分:5)
您可以隐式地将long
投射到double
。
您无法隐式地将double
投射到long
所以C#编译器决定你的变量类型的唯一可能性是double
。
答案 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());
换句话说,最好的解决方案可能不会使用三元运算符,但问题并没有给出足够的背景知识。