在为其赋值的if-else语句中使用未赋值的局部变量
本文关键字:赋值 局部变量 if-else 语句 | 更新日期: 2023-09-27 18:08:00
我有以下代码将一些字符串解析为双精度
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
正在使用时,它没有分配(使用未分配的局部变量'指数')。但是,即使以相同的方式处理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语句时被赋值吗?这两个代码示例在逻辑上不是等价的吗?这是编译器的限制吗?实际上,我有点惊讶编译器足够聪明,能够在第一个地方识别出底部代码示例中的情况。
我很确定你想要||
而不是&&
。目前,只有当和行都无效时才会抛出异常——如果第一行有效,则永远不会解析第二行。我假设你实际上只想使用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");
}
&&
短路,因此如果number
的解析失败,第二个TryParse
将永远不会执行,因此exponent
可以不初始化。
旁注-如果或解析失败,您希望失败,所以您真正想要的是OR (|
)而不是AND (&
)
- 将
&&
更改为||
以修复逻辑错误 颠倒逻辑,将"happy case"放在前面:
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");
不行,因为在上面的例子中,number和exponent都必须为空才能到达不可破坏的路径:
如果(!双。TryParse(line1, out number) &&双。TryParse(line2, out exponent))
this也不会编译:
如果(!双。TryParse(line1, out number) ||双。TryParse(line2, out exponent))
因为如果行失败(不是数字),那么在初始化exponent之前,您将退出if语句。你的第二个IF语句是正确的方法。