我有两种方法,它们都能正确编译:
public int A()
{
int i;
if(!int.TryParse("0", out i))
{
return -1;
}
// do sth
return i;
}
public int B()
{
int i;
if(true)
{
return -1;
}
return i;
}
在第二种情况下(方法B
),编译器足够聪明,可以检测到从未使用过变量i
,所以它不会抱怨没有分配它。
但是,我有另一个例子(两者的组合)似乎等同于方法B
:
public int C()
{
int i;
if (true || !int.TryParse("0", out i))
{
return -1;
}
return i;
}
在 VisualStudio 2012 ( .NET Framework 4.6.01055 )下的Windows上进行编译时,会抛出错误:Use of unassigned local variable 'i'
。解决方案是:
i
或|
运算符代替||
。为什么会这样?看起来编译器具有检测无法访问代码的所有必要数据。
旁注:示例C
在 mono 4.6.2 下的 Linux 上编译,并显示有关无法访问的代码的警告。< / p>
答案 0 :(得分:1)
这不能被视为一个错误,但它是一个可以改进的功能。当你说编译器有足够的信息知道从未使用过未分配的i
时,你是正确的,因此它应该省略编译器错误。
它的可以改进,因为事实上它已得到改善;在VS 2015中,编译器的行为是预期的:没有编译时错误。我不能对以前版本的编译器说同样的话,因为我现在无法对它们进行测试。
有趣的是,VS 2015或VS 2017 RC都没有在return i
报告无法访问的代码警告,这似乎有点奇怪。 if (true)
会正确地提供此警告和if (true || ....)
数字i
未被使用,但由于我不理解的原因而忽略了警告。
有关行为更改原因的更多信息,请查看此one。我知道这个问题响了一个钟......我几年前曾问过类似的问题;)。
答案 1 :(得分:0)
在Visual Studio 2012(.NET Framework 4.6.01055)下的Windows上进行编译时,会抛出错误:使用未分配的局部变量“i”
应该如此。该变量未分配。您可能不会在代码中引用它。有时候,根据编译器的不同,它可能事先知道该行永远不会执行,并在检查变量使用之前完全删除它。其他版本可能会切换可能导致不同结果的步骤。我个人会说你不应该依赖它:代码安全。
仅供参考。 Roslyn(最新的.NET编译器)在编译时不会出错。似乎验证只会丢弃所有||
条件。
if (true || !int.TryParse("0", out i)) // // does not give an error, first return always used, other discarded
if (true && !int.TryParse("0", out i)) // does not give an error, i is known to always be assigned
if (false && !int.TryParse("0", out i)) // gives an error, if never results in true, and parse is known not to be called