4 votes

Techniques pour traiter le message d'erreur "not all code paths return a value" lorsque votre algorithme en prend déjà compte

En C#, il arrive parfois qu'il y ait des chemins de code qui ne retournent pas de valeur, et c'est bien que le compilateur renvoie des erreurs et vous permette de les corriger. Cependant, il arrive parfois STRUCTURELLEMENT qu'il n'y ait pas d'endroit où il ne le fait pas, mais l'ALGORITHME empêcherait cette structure de se produire.

Voici un exemple simple et fabriqué.

public static int test1(bool a)
    {
        if (a) return 1;
        if (!a) return 2;
    }

Évidemment, les gens me diront que mon "algorithme" est stupide et que mon deuxième test est redondant et que je devrais simplement faire.

public static int test1(bool a)
    {
        if (a) return 1;
        else return 2;
    }

ou même

public static int test1(bool a)
    {
        if (a) return 1;
        return 2;
    }

J'ai choisi délibérément cet exemple "redondant" simple, plutôt que mes algorithmes du monde réel, car je veux me concentrer spécifiquement sur ce problème, et non sur les 10 différentes façons dont j'aurais pu écrire l'algorithme :)

Alors, quelles sont les façons possibles de traiter cela, et quels sont les avantages et les inconvénients de chacune.

1) est ce que nous venons de couvrir, et c'est refactoriser l'algorithme. Parfois, cela peut ne pas être possible, ou le résultat final peut ne pas être aussi performant, facile à lire/comprendre ou à entretenir.

une autre consiste simplement à retourner quelque chose qui ne se produira jamais, comme null... mais dans ce cas, je travaille avec un entier et je devrais mettre 0, ce qui semble encore plus sale.

public static int test1(bool a)
    {
        if (a) return 1;
        if (!a) return 2;
        //ce code n'arrive jamais, mais je dois garder le compilateur satisfait
        return 0;
    }

ou utiliser des exceptions

public static int test1(bool a)
    {
        if (a) return 1;
        if (!a) return 2;
        throw new Exception("ce code n'arrive jamais, mais je dois garder le compilateur satisfait");
    }

Cependant, à chaque fois que j'ai traité avec cela, quel que soit la technique que j'utilise, je ne suis pas satisfait du résultat et je me sens un peu mal à l'aise.

Y a-t-il des alternatives?

4voto

Ryan Amies Points 1872

Généralement, vous lancez des Exceptions lorsqu'il y a un cas exceptionnel... un booléen n'étant ni true ni false serait plutôt exceptionnel! Je lancerai une exception pour satisfaire le compilateur, mais aussi parce que vous ne savez pas comment la méthode pourrait évoluer à l'avenir.

Je ne considérerais pas un if ... else comme sale lorsqu'il s'agit d'un booléen pour la simple raison que vous utilisez des booléens, ils n'ont que deux valeurs, lorsqu'il y a plus de possibilités (par exemple une chaîne de caractères) alors vous pouvez utiliser des tests plus complexes.

3voto

User Points 1088

Lorsque vous avez une erreur de compilation indiquant que toutes vos trajectoires de code ne renvoient pas de valeur, il n'y a pas de drapeau à définir ou de "truc", vous devez soit renvoyer une valeur par défaut, soit lever une exception. Je suis convaincu qu'il est nécessaire de lancer une InvalidOperationException("Code inattendu atteint, cette méthode a été modifiée de manière incorrecte").

Pourquoi ce n'est pas sale : si quelqu'un d'autre vient et apporte une modification qui provoque le déclenchement de votre exception, ils sauront qu'ils ont fait quelque chose que l'auteur de l'exception considère fondamentalement incorrect. Renvoyer une valeur par défaut pourrait casser silencieusement les consommateurs de la méthode, il est donc bon de pratiquer l'utilisation d'une exception comme filet de sécurité.

0voto

legrandviking Points 1283
    public static int test1(bool a)
    {
        return a ? 1 : 2;
    }

0voto

OneFineDay Points 8899

Utilisez une variable et assignez-lui la valeur, puis retournez cette valeur à la fin de la fonction.

private bool isValid() 
{
bool result = false;
try {
    //some code 
    result = true;
    } catch {
    result = false;
    }
return result;
}

0voto

Asaf Points 3203

Une autre option que vous pourriez envisager dans ce cas est d'utiliser la méthode Debug.Fail().

public static int test1()
{
    if (myComplexAlgo()) return 1;
    if (myCatchAllAlgo()) return 2;
    Debug.Fail("Je ne devrais jamais me retrouver ici !");
    return -1;
}

Ce n'est pas adapté à tout le monde, l'avantage de cette méthode est que vous pouvez l'utiliser pour vous assurer que vos tests échouent sans risquer de planter votre code de production. Cela peut (espérons-le) détecter des problèmes futurs dans le code au cas où votre algorithme ou vos conditions changeraient.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X