20 votes

L'exception correcte à lancer pour un cas de commutation non géré pour un argument ?

NOTE : Ceci est différent des doublons proposés car cela traite d'un argument plutôt que d'une valeur. Le comportement et les scénarios applicables sont essentiellement différents.

Disons que nous avons SomeEnum et avoir une déclaration de commutation qui le gère comme :

enum SomeEnum
{
    One,
    Two,
}

void someFunc(SomeEnum value)
{
    switch(value)
    {
        case SomeEnum.One:
            ...
            break;
        case SomeEnum.Two:
            ... 
            break;
        default:
            throw new ??????Exception("Unhandled value: " + value.ToString());    
    }
}

Comme vous le voyez, nous gérons toutes les valeurs possibles de l'enum, mais nous conservons une exception par défaut au cas où un nouveau membre serait ajouté et que nous voulions nous assurer que nous sommes conscients du traitement manquant.

Ma question est la suivante : quelle est la bonne exception dans de telles circonstances où vous voulez notifier que le chemin de code donné n'est pas traité/implémenté ou n'aurait jamais dû être visité ? Nous avions l'habitude d'utiliser NotImplementedException mais ça ne semble pas être la bonne solution. Notre prochain candidat est InvalidOperationException mais le terme ne sonne pas juste. Quel est le bon terme et pourquoi ?

EDITAR : Introduction de C# 8.0 expressions de commutation qui produisent des avertissements du compilateur pour les instructions de commutation non-exhaustives. C'est une autre raison pour laquelle vous devriez utiliser des expressions switch plutôt que des instructions switch chaque fois que cela est possible. La même fonction peut être écrite d'une manière plus sûre comme :

void someFunc(SomeEnum value)
{
    _ = value switch
    {
        SomeEnum.One => ....,
        SomeEnum.Two => ...., 
    }
}

Quand un nouveau membre est ajouté à SomeEnum le compilateur affichera l'avertissement "CS8509 : L'expression switch ne gère pas toutes les valeurs possibles de son type d'entrée (elle n'est pas exhaustive). Par exemple, le motif 'EnumHandling.SomeEnum.Three' n'est pas couvert." pour l'expression du commutateur, ce qui facilite grandement la détection des bogues potentiels.

23voto

Oded Points 271275

ArgumentException me semble la plus correcte dans ce cas (bien qu'elle ne soit pas définie dans la BCL).

Il existe une exception spécialisée pour les arguments de type "enum". InvalidEnumArgumentException :

L'exception déclenchée lors de l'utilisation d'arguments invalides qui sont des énumérateurs.

Une alternative est ArgumentOutOfRangeException :

L'exception qui est levée lorsque la valeur d'un argument se situe en dehors de la plage de valeurs autorisée définie par la méthode invoquée.

La logique qui sous-tend leur utilisation est que l'argument transmis ( value ) n'est pas valable dans la mesure où someFunc est concerné.

17voto

CR41G14 Points 1918

Je jetterais le InvalidEnumArgumentException car il donnera des informations plus détaillées dans ce cas, vous vérifiez un enum.

4voto

Habib Points 93087

Puisque vous avez le login dans une fonction, vous pouvez lancer InvalidArgumentException .

L'exception qui est soulevée lorsqu'un paramètre qui n'est pas valide est passé à une méthode sur la connexion référencée au serveur.

EDITAR: Une meilleure alternative serait : ArgumentException ya que InvalidArgumentException en Microsoft.SqlServer.Management.Common espace de noms. Quelque chose comme :

throw new ArgumentException("Unhandled value: " + value.ToString());

0voto

Manibhadra Points 400

InvalidArgumentException. Lorsque l'utilisateur passe une valeur non valide ou une valeur nulle alors qu'une valeur est requise, il est recommandé de traiter l'exception InvalidArgumentException .

0voto

Matthew Watson Points 30804

Si vous utilisiez des Contrats de code (ce que je HAUTEMENT recommander), vous le placerez au début de la méthode :

Contract.Requires(value == SomeEnum.One || value == SomeEnum.Two);

Si vous voulez vérifier une plage d'un enum qui a trop de valeurs individuelles pour les écrire toutes explicitement, vous pouvez le faire comme ceci :

Contract.Requires(SomeEnum.One <= value && value <= SomeEnum.Two);

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