C#编译器错误:"并非所有代码路径都返回值"。

61

我正在尝试编写代码,以返回一个给定整数是否可以被1到20均匀地整除,但我不断收到以下错误:

error CS0161: 'ProblemFive.isTwenty(int)': 不是所有的代码路径都返回一个值

这是我的代码:

public static bool isTwenty(int num)
{
    for(int j = 1; j <= 20; j++)
    {
        if(num % j != 0)
        {
            return false;
        }
        else if(num % j == 0 && num == 20)
        {
            return true;
        }
    }
}

7
你的代码没有意义,但错误信息很清晰。即使你的 if 条件在 20 次迭代中都为 false,你仍需要返回一个值。 - ChaosPandion
10
你的思维方式更像是人类,而不是编译器。编译器并不知道你在想什么,或者逻辑应该如何流动(除了过去的优化)。如果一个值既不匹配第一个‘if’,也不匹配第二个‘if’,会发生什么? - GrandmasterB
9个回答

115

你缺少了一个return语句。

当编译器查看你的代码时,它会看到第三条路径(你没有编写的else)可能会发生但不返回值。因此,not all code paths return a value

对于我的建议修复,我在循环结束后添加了一个return。另一个明显的位置——在if-else-if中添加一个有return值的else——会破坏for循环。

public static bool isTwenty(int num)
{
    for(int j = 1; j <= 20; j++)
    {
        if(num % j != 0)
        {
            return false;
        }
        else if(num % j == 0 && num == 20)
        {
            return true;
        }
    }
    return false;  //This is your missing statement
}

1
这会返回错误的结果,对于 isTwenty(44696171520)。它应该返回 true,因为它可以被1到20的所有数字均匀地整除,但它返回 false。实际上,它总是返回 false,因为它永远无法进入条件,其中它将返回 true - Guffa
1
@Guffa - 我认为由于这个问题看起来像是 GlenH7 在做家庭作业,他只是在做最少的工作以使代码编译通过,而没有修复逻辑错误。 - James Snell
1
另一个选项是抛出异常而不是返回可能错误的值,这将揭示逻辑错误并帮助学生学习。 - James Snell
4
@Guffa - 我有点羞愧地承认我没有尝试去解密函数的其余部分,而是专注于OP提到的错误。我对OP的逻辑表达同样感到困惑,但我选择忽略它,以回答被问到的问题。 - user1345223

10
编译器无法理解你在循环的最后一次迭代中返回的复杂逻辑,因此它认为你可能会退出循环而最终没有返回任何内容。

不要在最后一次迭代中返回,而是在循环结束后返回true:

public static bool isTwenty(int num) {
  for(int j = 1; j <= 20; j++) {
    if(num % j != 0) {
      return false;
    }
  }
  return true;
}

顺便提一下,原始代码中存在逻辑错误。在最后一个条件中,您正在检查 num == 20 ,但应该检查 j == 20 。此外,在那里检查是否 num%j == 0 是多余的,因为当你到达那里时,它总是成立的。


9

我也遇到了这个问题,发现了一个简单的解决方法:

public string ReturnValues()
{
    string _var = ""; // Setting an innitial value

    if (.....)  // Looking at conditions
    {
        _var = "true"; // Re-assign the value of _var
    }

    return _var; // Return the value of var
}

这也适用于其他返回类型,并且会产生最少的问题。

我选择的初始值是一个后备值,我可以根据需要重新分配该值多次。


7

我喜欢啰嗦,但我只想再强调一点:

首先,问题在于你的控制结构没有涵盖所有条件。基本上,你说如果 a ,那么这样做;否则,如果 b ,那么那样做。结束。但如果两者都不是呢?就没有退出的方式了(即并非每个“路径”都返回值)。

我的额外观点是,这就是为什么你应该尽可能地看重单一的退出方式。在这个例子中,你应该这样做:

bool result = false;
if(conditionA)
{
   DoThings();
   result = true;
}
else if(conditionB)
{
   result = false;
}
else if(conditionC)
{
   DoThings();
   result = true;
}

return result;

因此,在这里,您将始终拥有一个返回语句,并且该方法始终在一个位置退出。但是需要考虑一些事情...您需要确保每个路径上的退出值都是有效的,或者至少是可接受的。例如,此决策结构仅考虑三种可能性,但单个退出也可以作为最终的else语句。或者不是这样吗?您需要确保最终的返回值在所有路径上都是有效的。与具有5000万个退出点相比,这是更好的方法。


3

或者简单地做这个:

public static bool isTwenty(int num)
{
   for(int j = 1; j <= 20; j++)
   {
      if(num % j != 0)
      {
          return false;
      }
      else if(num % j == 0 && num == 20)
      {
          return true;
      }
      else
      {
          return false; 
      }
   }
}

1
这会“破坏”原帖代码的(极具争议的)逻辑,因为它总是在循环的第一次迭代中返回。 - El Ronnoco

1
class Program
{
    double[] a = new double[] { 1, 3, 4, 8, 21, 38 };
    double[] b = new double[] { 1, 7, 19, 3, 2, 24 };
    double[] result;


    public double[] CheckSorting()
    {
        for(int i = 1; i < a.Length; i++)
        {
            if (a[i] < a[i - 1])
                result = b;
            else
                result = a;
        }
        return result;
    }

    static void Main(string[] args)
    {
        Program checkSorting = new Program();
        checkSorting.CheckSorting();
        Console.ReadLine();
    }
}

这应该能够工作,否则我会得到一个错误,提示并非所有的代码路径都返回了值。因此,我将结果设置为返回值,该返回值根据真实情况设置为 B 或 A。


1

看看这个。它是C#中的三元运算符。

bool BooleanValue = (num % 3 != 0) ? true : false;

这只是为了展示原理;你可以根据问题标记左侧的结果返回True或False(甚至整数或字符串)。这个操作符很好用。
三个选项一起:
      public bool test1()
        {
            int num = 21;
            bool BooleanValue = (num % 3 != 0) ? true : false;
            return BooleanValue;
        }

        public bool test2()
        {
            int num = 20;
            bool test = (num % 3 != 0);
            return test;
        }

更简短:
public bool test3()
{
    int num = 20;
    return (bool)(num % 3 != 0);
}

1

如果我错放了一个return语句,通常会出现这种情况: 输入图像描述

添加一个return语句,或者像我一样将它移动到正确的作用域即可解决问题: 输入图像描述


6
最好使用直接的代码而不是图片 - 如果视力受损的用户正在使用网站,他们无法使用TTS来阅读此答案,但如果您将代码复制为文本,他们可以。 - Lou

-1

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

解决方案:为了解决这个错误,在函数中确保从所有的代码路径返回一个值,或者在你的 tsconfig.json 文件中将 noImplicitReturns 设置为 false。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接