真的有一个有效的代码路径,该函数不会返回值吗?

时间:2019-04-06 00:11:59

标签: c# compiler-errors csc

我具有下面的函数,该函数遍历工作列表,调用其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块中的条件?

3 个答案:

答案 0 :(得分:2)

  1. 如果最后一个索引上引发异常,并且计数不是您期望的那样(不太可能)

  2. 或如RAM指出Count是否为零

在这种情况下,静态分析和随后的编译器错误是很合理的

答案 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;
}