在以下代码中,我期望var
可以解析为Int64
,但它会解析为double
。为什么这样?为什么var会以Double而不是Long来解析?
string a = "1234";
bool asInt = true;
var b = (asInt) ? Int64.Parse(a) : Double.Parse(a) ;
Console.WriteLine(b.GetType());
在以下代码中,我期望var
可以解析为Int64
,但它会解析为double
。为什么这样?为什么var会以Double而不是Long来解析?
string a = "1234";
bool asInt = true;
var b = (asInt) ? Int64.Parse(a) : Double.Parse(a) ;
Console.WriteLine(b.GetType());
有一个隐式转换从Int64
到Double
而不是其他方式(由于在该方向上的精度可能损失)。
由于条件的两个“分支”都需要解析为相同类型,因此b
的类型最终被推断为Double
。
有道理。有什么办法可以在需要时创建Int64类型的变量'b',并在需要时创建Double(基于bool'asInt')?当然,在if语句中初始化它是行不通的,因为它的作用域限制在 – xbonez 2012-02-14 12:35:02
@xbonez - 不在条件运算符中。该类型必须在运行时推断/确定。你可以使用'dynamic'。 – Oded 2012-02-14 12:36:38
嗯...谢谢。我会研究动态的。我知道数学运算在双打上比较慢,所以我希望在不需要时不要使用双精度。我会研究动态的,但如果这不起作用,我想我会忍受它。 – xbonez 2012-02-14 12:37:52
您可以隐式将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());
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
我很惊讶,没有人指出,如果你知道值将是一个法律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());
换句话说,它可能是最好的解决办法不会用三元运算符,但问题并没有给予足够的情况下就知道了。
即使编译,我有点惊讶。我认为三元的两边都必须返回相同的类型,尽管我认为有一个从长到双的隐含对话 – 2012-02-14 12:32:36
有。 ,)这解释了这一点。 – TomTom 2012-02-14 12:34:07