c# erro de retorno "nem todos os caminhos de código retornam um valor"

estou a tentar escrever um código que devolve se um dado inteiro é divisível uniformemente por 1 a 20,
mas continuo a receber o seguinte erro:

erro CS0161: 'ProblemFive.isTwenty (int)": nem todos os caminhos de código devolvem um valor

Aqui está o meu código:
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;
        }
    }
}
 29
Author: Steven, 2014-01-18

8 answers

Falta-te uma declaração.

Quando o compilador olha para o seu código, vê um terceiro caminho (o else para o qual você não codifica) que pode ocorrer mas não devolve um valor. Daí not all code paths return a value.

Para a minha solução sugerida, coloquei um após o fim do teu laço. O outro ponto óbvio-adicionando um else que tinha um valor return para o if-else-if - quebraria o laço 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
}
 65
Author: GlenH7, 2014-01-18 14:01:12

O compilador não tem a lógica intrincada onde você retorna na última iteração do loop, então ele acha que você pode sair do loop e acabar não devolvendo nada de todo.

Em vez de voltar na última iteração, apenas retorne verdadeiro após o loop:

public static bool isTwenty(int num) {
  for(int j = 1; j <= 20; j++) {
    if(num % j != 0) {
      return false;
    }
  }
  return true;
}
Nota de lado, há um erro lógico no código original. Está a verificar se num == 20 na última condição, mas devia ter verificado se j == 20. Também a verificar se num % j == 0 era superflous, pois que é sempre verdade quando se chega lá.
 8
Author: Guffa, 2014-01-17 21:48:39

Eu também experimentei este problema e encontrei a solução fácil para ser

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
}

Isto também funciona com outros tipos de retorno e dá a menor quantidade de problemas

O valor inicial que escolhi foi um valor de retorno e fui capaz de atribuir o valor tantas vezes quanto necessário.

 6
Author: Evert, 2014-07-27 14:47:14

Ou simplesmente fazer estas coisas:

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

}
 3
Author: DareDevil, 2014-02-05 12:25:49
Gosto de bater em cavalos mortos, mas só queria dizer mais uma coisa: Em primeiro lugar, o problema é que nem todas as condições da sua estrutura de controlo foram abordadas. Essencialmente, estás a dizer que se a, então isto, se b, Então Isto. Final. Mas e se nenhum deles? Não há forma de sair (ou seja, nem todos os 'path' devolvem um valor).

O meu ponto adicional é que este é um exemplo de porque você deve apontar para uma única saída, se possível. Neste exemplo você faria algo do género:

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

return result;
Então, aqui, você sempre uma declaração de retorno e o método sempre sai em um lugar. Mas há algumas coisas a considerar... você precisa se certificar de que seu valor de saída é válido em todos os caminhos ou pelo menos aceitável. Por exemplo, esta estrutura de decisão representa apenas três possibilidades, mas a saída única também pode funcionar como a sua última declaração. Ou será? Você precisa se certificar de que o valor final de retorno é válido em todos os caminhos. Esta é uma maneira muito melhor. aproximar-se contra ter 50 milhões de pontos de saída.
 2
Author: Sinaesthetic, 2014-01-27 06:29:35
Olha para este. É o operador ternário em C#.
bool BooleanValue = (num % 3 != 0) ? true : false;

Isto é apenas para mostrar o princípio; você pode retornar verdadeiro ou falso (ou mesmo inteiro ou string) dependendo do resultado de algo no lado esquerdo do ponto de interrogação. Belo operador, este.

Três alternativas juntas:

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

Ainda Mais Curto:

public bool test3()
{
    int num = 20;
    return (bool)(num % 3 != 0);
}
 1
Author: netfed, 2014-01-18 23:06:23
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();
    }
}
Isto deve funcionar, caso contrário tenho o erro de que nem todos os codepaths devolvem um valor. Para isso, defini o resultado como o valor devolvido, que é definido como B ou A dependendo do que é verdadeiro
 1
Author: Douglas Pettersson, 2017-06-01 13:16:31
Tive este erro ao tentar abrir um projecto VS 2017 em VS 2015. Claro que a solução estava aberta em 2017.
 0
Author: webdev5, 2018-09-13 17:37:02