我有以下代码将一些字符串解析为双精度
double number;
double exponent;
if(!double.TryParse(line1, out number) &&
!double.TryParse(line2, out exponent))
throw new ArgumentException("Invalid string");
else
number *= 10.0 * exponent;
我在编译器中遇到错误,exponent
在未分配时使用(使用未分配的局部变量'exponent')。但是,我没有得到number
变量的错误,即使它以相同的方式处理。另外,&&
与if语句中调用的函数中的out
说明符相结合,应该保证在到达else块时分配数字和指数。
以下代码已编译。
double number;
double exponent;
if(!double.TryParse(line1, out number))
throw new ArgumentException("Invalid string");
else{
if(!double.TryParse(line2, out exponent)){
throw new ArgumentException("Invalid string");
}else{
number *= 10.0 * exponent;
}
}
为什么会这样?在第一个代码示例中,并不是两个变量都保证在执行else语句时分配?两个代码示例在逻辑上是否等效?这是编译器的限制吗?实际上,我很惊讶编译器足够聪明,可以在底部代码示例中识别出这个案例。
答案 0 :(得分:6)
我很确定您需要||
而不是&&
。目前,如果两个行无效,则只会抛出异常 - 如果第一行有效,则您甚至不会解析第二行。我假设您实际上只想使用number
和exponent
,如果它们都有效...
所以你的代码应该是(有更多的惯用格式):
if (!double.TryParse(line1, out number) || !double.TryParse(line2, out exponent))
{
throw new ArgumentException("Invalid string");
}
else
{
number *= 10.0 * exponent;
}
或者让整个事情更容易理解,减少所涉及的负面数量 - 如果 有效,则显示您想要做的事情,并处理else
中的负面情况:
if (double.TryParse(line1, out number) && double.TryParse(line2, out exponent))
{
number *= 10.0 * exponent;
}
else
{
throw new ArgumentException("Invalid string");
}
答案 1 :(得分:3)
&&
短路,因此如果解析number
失败,则第二个TryParse
将永远不会执行,因此exponent
可能会保持未初始化状态。
附注 - 如果要么解析失败,你想要失败,所以你真的想要OR(|
)而不是AND(&
)
一些选项:
&&
更改为||
以修复逻辑错误颠倒逻辑,将“快乐案例”放在第一位:
double number;
double exponent;
// you can use "&&" here because you don't reference exponent unless both parses succeed.
if(double.TryParse(line1, out number) &&
double.TryParse(line2, out exponent))
{
number *= 10.0 * exponent;
}
else
throw new ArgumentException("Invalid string");
答案 2 :(得分:0)
不,因为在你的顶级示例中,number和exponent都必须为null才能到达不可破坏的路径:
if(!double.TryParse(line1,out number)&& !double.TryParse(line2,out exponent))
这将无法编译:
if(!double.TryParse(line1,out number)|| !double.TryParse(line2,out exponent))
因为如果行失败(不是数字),那么在初始化exponent之前,你将摆脱IF语句。你的第二个IF声明是正确的做法。