“错误:并非所有代码路径都返回值

本文关键字:代码 路径 返回值 错误 | 更新日期: 2023-09-27 18:33:45

我的代码在编译时抛出名义上的异常。我不明白为什么会发生这种情况,因为经过广泛的搜索,错误发生的原因似乎只是当存在没有 exit return 语句的条件时,但我认为我的代码是完全包含的。

bool CheckExisting()
{
    Account loginAcc = new Account();
    string path = Application.StartupPath.ToString() + "''Customers";
    int fCount = Directory.GetFiles(path, "*.xml", SearchOption.AllDirectories).Length;
    for(int i = 0;i<fCount;i++)
    {
        String[] filePaths = Directory.GetFiles(Application.StartupPath + "''Customers''");
        XmlDocument xmlFile =new XmlDocument();
        xmlFile.Load(filePaths[i]);
        foreach(XmlNode node in xmlFile.SelectNodes("//Account"))
        {
            string firstName = node.SelectSingleNode("FirstName").InnerText;
            string lastName = node.SelectSingleNode("LastName").InnerText;
            string address1 = node.SelectSingleNode("Address1").InnerText;
            string address2 = node.SelectSingleNode("Address2").InnerText;
            string postCode = node.SelectSingleNode("Postcode").InnerText;
             string telePhone = node.SelectSingleNode("Telephone").InnerText;
            string mobile = node.SelectSingleNode("Mobile").InnerText;
            Account newAcc = new Account();
            newAcc.firstName = firstName;
            newAcc.lastName = lastName;
            newAcc.address1 = address1;
            newAcc.address2 = address2;
            newAcc.postCode = postCode;
            newAcc.telephone = telePhone;
            newAcc.mobile = mobile;
            loginAcc = newAcc;
        }
        if(txtFirstName.Text == loginAcc.firstName && txtLastName.Text == loginAcc.lastName)
        {
            return true;
        }
        else
        {
            return false;
        }
        return false;
    }
}

“错误:并非所有代码路径都返回值

您的代码实际上是:

bool CheckExisting()
{
    // Some setup code
    for (int i = 0; i < fCount; i++)
    {
        // Code which isn't terribly relevant
        return ...;
    }
}

现在,C# 5 语言规范第 8.8.3 节讨论了 for 语句结尾的可访问性:

如果满足以下至少一项条件,则可以到达for语句的终点:

  • for 语句包含一个可访问的 break 语句,该语句退出 for 语句。
  • for语句是可访问的,并且存在 for-条件,并且没有常量值true

在这种情况下,后者是正确的,因此可以到达for语句的结尾......方法到此结束。永远无法访问具有非 void 返回类型的方法的末尾。

请注意,即使有人可以检测到您永远无法到达 for 语句的末尾,情况也是如此。例如:

bool Broken()
{
    for (int i = 0; i < 5; i++)
    {
        return true;
    }
    // This is still reachable!
}

我们知道循环总是至少执行一次,但语言规则不会 - 因此语句的末尾是可访问的,并且您会收到编译时错误。

如果fCount为 0,那么您的循环将不会执行,并且您不会命中任何返回语句。

一些压缩和改进的缩进清楚地表明:

    int fCount = Directory.GetFiles(path, "*.xml", SearchOption.AllDirectories).Length;
    for(int i = 0;i<fCount;i++){
        ...
        if(txtFirstName.Text == loginAcc.firstName && txtLastName.Text == loginAcc.lastName){
            return true;
        }
        else{
            return false;
        }
        return false;
    }

可能在"现实世界"中,fCount 永远不能为 0,但是编译器/运行时不会知道这一点。

发生这种情况是因为在 for 循环之后你返回了 Nothing。

当方法执行时,它应返回您定义的类型。 当代码执行路径进入 for 语句时,它很好,因为它会返回。如果代码没有进入 for 循环,则您的代码不会返回任何内容。这就是错误。 Run time例外可能.用铅笔和纸浏览代码,看看它是如何执行的

您错过了退货。这应该有效。

bool CheckExisting()
{
        Account loginAcc = new Account();
        string path = Application.StartupPath.ToString() + "''Customers";
        int fCount = Directory.GetFiles(path, "*.xml", SearchOption.AllDirectories).Length;
        for(int i = 0;i<fCount;i++)
        {
            String[] filePaths = Directory.GetFiles(Application.StartupPath + "''Customers''");
            XmlDocument xmlFile =new XmlDocument();
            xmlFile.Load(filePaths[i]);
            foreach(XmlNode node in xmlFile.SelectNodes("//Account"))
            {
                string firstName = node.SelectSingleNode("FirstName").InnerText;
                string lastName = node.SelectSingleNode("LastName").InnerText;
                string address1 = node.SelectSingleNode("Address1").InnerText;
                string address2 = node.SelectSingleNode("Address2").InnerText;
                string postCode = node.SelectSingleNode("Postcode").InnerText;
                string telePhone = node.SelectSingleNode("Telephone").InnerText;
                string mobile = node.SelectSingleNode("Mobile").InnerText;
                Account newAcc = new Account();
                newAcc.firstName = firstName;
                newAcc.lastName = lastName;
                newAcc.address1 = address1;
                newAcc.address2 = address2;
                newAcc.postCode = postCode;
                newAcc.telephone = telePhone;
                newAcc.mobile = mobile;
                loginAcc = newAcc;
            }

            if(txtFirstName.Text == loginAcc.firstName && txtLastName.Text == loginAcc.lastName)
            {
                return true;
            }
            else
            {
                return  false;
            } 
        return false;       
        }
      return false;
    }
bool CheckExisting(){
    Account loginAcc = new Account();
    string path = Application.StartupPath.ToString() + "''Customers";
    int fCount = Directory.GetFiles(path, "*.xml", SearchOption.AllDirectories).Length;
    for(int i = 0;i<fCount;i++){
        String[] filePaths = Directory.GetFiles(Application.StartupPath + "''Customers''");
        XmlDocument xmlFile =new XmlDocument();
        xmlFile.Load(filePaths[i]);
        foreach(XmlNode node in xmlFile.SelectNodes("//Account")){
            string firstName = node.SelectSingleNode("FirstName").InnerText;
            string lastName = node.SelectSingleNode("LastName").InnerText;
            string address1 = node.SelectSingleNode("Address1").InnerText;
            string address2 = node.SelectSingleNode("Address2").InnerText;
            string postCode = node.SelectSingleNode("Postcode").InnerText;
            string telePhone = node.SelectSingleNode("Telephone").InnerText;
            string mobile = node.SelectSingleNode("Mobile").InnerText;
            Account newAcc = new Account();
            newAcc.firstName = firstName;
            newAcc.lastName = lastName;
            newAcc.address1 = address1;
            newAcc.address2 = address2;
            newAcc.postCode = postCode;
            newAcc.telephone = telePhone;
            newAcc.mobile = mobile;
            loginAcc = newAcc;
        }

        if(txtFirstName.Text == loginAcc.firstName && txtLastName.Text == loginAcc.lastName){
            return true;
        }
        else{
            return false;
        }
    return false;
    }
??????
}

如果您没有进入 for 循环,则不返回任何内容。或者,如果您的"FCount"为"0",则您不会返回任何内容。

简单地说,只需在末尾添加一个默认return false。下面是您的代码片段:

        if(txtFirstName.Text == loginAcc.firstName && txtLastName.Text == loginAcc.lastName)
        {
            return true;
        }
        else
        {
            return false;
        }
        return false;
    }
        return false;
}

只要考虑一下fCount小于它的情况场景。

for(int i = 0;i<fCount;i++)

将跳过 for 循环。那么返回语句在哪里呢?这就是编译器抛出此错误的原因。

我想你的意思是这样做:(我正在窃取CodeCaster的清理版本(

bool CheckExisting()
{
    //
    for(/**/)
    {
        //
        foreach(/**/)
        {
            //
        }
        if(/**/)
        {
            return true;
        }
        else
        {
            return false;
        }
        // return false; NOT HERE, because it's not reachable in the first place.
    }
    return false; // BUT HERE, in case fCount = 0
}

此外,您可以在最后取消if-else,然后只做

return txtFirstName.Text == loginAcc.firstName && txtLastName.Text == loginAcc.lastName;

。因为这已经是一个布尔表达式。