代码之家  ›  专栏  ›  技术社区  ›  Craig

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

  •  0
  • Craig  · 技术社区  · 6 年前

    // 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块中的条件?

    2 回复  |  直到 6 年前
        1
  •  2
  •   TheGeneral    6 年前

    是的

    1. 或作为 RAM 指出如果 Count

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

        2
  •  2
  •   philazzi44    6 年前

    如前所述,如果worker为空(Count为0),则没有有效的返回路径。

    还有另一个竞争条件(显然,取决于完整的上下文),其中 workers 如果不为空,则在元素上引发异常,仍有元素要迭代 工人 , 但是 if (i == workers.Count - 1) 之前 这个 continue 语句执行时,另一个线程从 工人 (或改变整个 工人 新实例的变量)。

    for

    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
                {
                    // XXX If workers is changed by another thread here. XXX
                    continue; // Try the next worker
                }
            }
        }
    }
    
        3
  •  1
  •   Ramin Bateni    6 年前

    我给你写了一条评论:

    工人列表项的计数 ?

    似乎这是编译器的问题,它没有做更多的研究您的代码!:)

    事实上

    并非所有代码路径都返回值

    是的,即使我们按照循环执行的方式设置循环的条件!

    证明:

    有错误:

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