C# 在赋值的if-else语句中使用未赋值的局部变量

C# 在赋值的if-else语句中使用未赋值的局部变量,c#,parsing,compiler-errors,C#,Parsing,Compiler Errors,下面的代码将一些字符串解析为双精度 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; 我在编译器中发现一个错误,即未赋值时使用了指

下面的代码将一些字符串解析为双精度

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语句时赋值吗?这两个代码示例在逻辑上不是等价的吗?这是编译器的限制吗?事实上,我有点惊讶编译器竟然聪明到可以首先识别底部代码样本中的大小写。

&&
短路,因此如果对
数字
的解析失败,第二个
TryParse
将永远不会执行,因此
指数
可能会被忽略

旁注-如果解析失败,您希望失败,因此您确实希望使用OR(
|
)而不是AND(
&

一些选择:

  • &&
    更改为
    |
    ,以修复逻辑错误
  • 颠倒逻辑,将“快乐案例”放在第一位:


我很确定你想要的是
|
而不是
&&
。目前,只有在两行都无效的情况下才会抛出异常-如果第一行有效,则永远不会解析第二行。我假设您实际上只想使用
数字
指数
,如果两者都有效

因此,您的代码应该是(具有更惯用的格式):

或者,为了使整个事情更容易理解,减少所涉及的负面因素的数量——如果一切都有效,展示你想做的事情,并在
else
中处理负面情况:

if (double.TryParse(line1, out number) && double.TryParse(line2, out exponent))
{
    number *= 10.0 * exponent;
}
else
{
    throw new ArgumentException("Invalid string");
}

不,因为在上面的示例中,数字和指数都必须为null才能到达不可中断的路径:

如果(!double.TryParse)(第1行,输出编号)&& !double.TryParse(第2行,输出指数))

这也不会编译:

如果(!double.TryParse)(第1行,输出编号)|| !double.TryParse(第2行,输出指数))


因为如果行失败(不是一个数字),那么在初始化指数之前就退出if语句。您的第二个IF语句是正确的方法。

在第二个示例中,您为什么编写&而不是| |?在第二个示例中,您何时声明指数?doh!这是一个我没有注意到的愚蠢的错误!我真不敢相信我被困在这里有一段时间了……@MichaelMcPherson我亲手写的代码。我忘记申报了。我编辑了我的问题来修正它。嘿,至少问题解决了。一定要接受有帮助的答案!将
&&
更改为
&
将导致“一切正常”的情况,但我怀疑OP并不是真的想这样做。@jonsket True-我专注于编译器错误而忽略了逻辑错误。我正在使用&。。但我明白你的意思。这是一个愚蠢的错误,我没有注意到:/谢谢@9a3eedi:是的,这是我的观点-你在使用
&
,但你不应该这样。@JonSkeet我想说的是这样一句话:“我很确定你想要
&
而不是
|
”,这意味着我在使用
|
,而我不是。我想你是想说“我很确定你想要的是
|
而不是
&&
”)无论是
数字
还是
指数
都不能精确为空!这就是为什么他的逻辑不起作用。。。如果数字是有效数字,则If在计算第二个数字并查看是否可以为指数赋值之前终止。
if (!double.TryParse(line1, out number) || !double.TryParse(line2, out exponent))
{
    throw new ArgumentException("Invalid string");
}
else
{
    number *= 10.0 * exponent;
}
if (double.TryParse(line1, out number) && double.TryParse(line2, out exponent))
{
    number *= 10.0 * exponent;
}
else
{
    throw new ArgumentException("Invalid string");
}