我具有下面的函数,该函数遍历工作列表,调用其DoStuff()方法。如果第一个工人失败了,我将尝试下一个,直到我没有工人为止。如果它们全部失败,我将抛出最后一个异常。
// workers is an IList<>.
public object TryDoStuff()
{
for (int i = 0; i < workers.Count; i++)
{
try
{
return worker[i].DoStuff();
}
catch
{
if (i == workers.Count - 1)
{
throw; // This preserves the stack trace
}
else
{
continue; // Try the next worker
}
}
}
}
编译时,出现错误,指出此函数“并非所有代码路径都返回值”。尽管我可以通过在for循环后添加显式返回来使错误静音,但是我怀疑编译器在此处是否正确,因为我看不到在不返回或重新引发异常的情况下如何转义for循环。而且,如果重新抛出异常,则不返回值是有效的。
我想念什么? csc是否无法推断出catch块中的条件?
答案 0 :(得分:2)
答案 1 :(得分:2)
如前所述,如果worker为空(Count为0),则没有有效的返回路径。
还有另一种竞争条件(显然取决于整个上下文),其中workers
不为空,元素上引发异常,workers
中仍有要迭代的元素,但是在评估if (i == workers.Count - 1)
和之前执行continue
语句之后,另一个线程从workers
中删除了元素(或更改了整个{{1} }变量添加到新实例)。
在这种情况下,workers
条件将在下一次迭代中意外返回false,并且您将陷入循环,而该方法没有return语句。
for
答案 2 :(得分:1)
我写给你的评论是
如果工人列表项的数量会发生什么? 零?
似乎这是编译器的问题,它不需要对您的代码做更多的研究! :)
实际上这个原因足以使编译器向您显示以下错误
并非所有代码路径都返回值
当编译器在整个方法主体中遇到循环时,它会假定该循环条件导致忽略该循环主体,那么它也希望该循环之外的任何值。
是的,即使我们以执行循环的方式设置循环的条件!
证明:
有错误:
public static object TryDoStuff()
{
var result =0;
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Add 100 unit");
result += 100;
return result;
}
//Console.WriteLine("last line");
// return result;
}
没有错误:
public static object TryDoStuff()
{
var result =0;
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Add 100 unit");
result += 100;
// return result; you can un-comment this line too
}
Console.WriteLine("last line");
return result;
}