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

时间:2014-12-09 14:43:13

标签: c# for-loop return return-value

我的代码在编译时抛出了名义上的异常。我不明白为什么会发生这种情况,因为在广泛搜索之后,错误发生的原因似乎只有当条件存在且没有退出返回语句时,我认为我的代码是完全包容的。

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

7 个答案:

答案 0 :(得分:6)

您的代码是有效的:

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-condition 存在,并且没有常量值true
  •   

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

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

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

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

答案 1 :(得分:3)

如果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,但编译器/运行时不会知道这一点。

答案 2 :(得分:2)

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

当你的方法执行时,它应该返回你定义的类型。当代码执行路径进入for语句时,它很好,因为它返回。如果代码没有进入for循环,那么代码不会返回任何内容。 这是错误。可能会出现Run time异常。使用铅笔和纸张浏览代码,看看它是如何执行的

答案 3 :(得分:1)

你错过了回归。这应该有用。

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

答案 4 :(得分:1)

我认为你打算这样做:(我偷了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;

...因为那是一个布尔表达式。

答案 5 :(得分:1)

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循环,

不返回任何内容。 或者如果您的&#34; FCount&#34;是&#34; 0&#34;。

答案 6 :(得分:1)

简单地说,只需在末尾添加默认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循环。那么返回声明在哪里呢?这就是编译器抛出此错误的原因。