9
votes

C #: La valeur par défaut d'un énumé doit-elle être ni inconnue?

Dites que vous avez un énumé qui représente un code d'erreur. Il y aura plusieurs codes, chacun avec sa propre valeur Int sous-jacente; Toutefois, la valeur Enum qui obtient la valeur 0 par défaut semble que cela devrait être soigneusement considérée.

Dans le cas d'un code d'erreur Enum, il y a deux valeurs spéciales que je peux penser: Aucun (pour les cas où il n'y a pas de erreur) et inconnu (pour les cas où aucun code d'erreur existant n'est approprié, ou peut-être même lorsque l'état d'erreur ne peut pas être détecté).

Une de ces valeurs semble être 0, où l'autre obtiendra probablement quelque chose d'autre comme -1. Est-il plus approprié de définir la valeur Aucun sur 0 ou la valeur inconnue à 0? xxx

Mon instinct me dit que la valeur par défaut devrait être inconnue, mais je suis curieux Si quelqu'un l'a fait différemment.


0 commentaires

9 Réponses :


2
votes

Pourquoi retourner une valeur de code d'erreur du tout quand il n'y a pas d'erreur?

ne fait pas beaucoup de sens. Supprimer cela résoudrait votre problème. Vous pouvez simplement faire 0 être pour inconnu: xxx

update

Votre commentaire est un peu effrayant. Vous ne devez jamais avoir une méthode qui renvoie un type de code d'erreur. C'est une très mauvaise pratique. Comme les codes d'erreur ne doivent être retournés dans des circonstances exceptionnelles, c'est une bonne idée de lancer des exceptions.

Si vous le souhaitez, vous pouvez avoir un champ dans votre exception personnalisée contenant la valeur de code d'erreur.


4 commentaires

Si la signature de votre fonction est Erreur publiqueCode Dofoo () , qu'est-ce que vous revenez lorsque la fonction a réussi?


@Karmastan - Je n'aurais jamais de méthode qui renvoie un code d'erreur. J'aurais une exception personnalisée qui est lancée et contient le code d'erreur à l'intérieur.


Le cadre utilise des codes d'erreur lorsque vous connaissez une opération peut échouer dans des circonstances normales. Par exemple, int32.tryparse renvoie une valeur au lieu de jeter une exception. J'utilise également des codes d'erreur sur les méthodes de validation où je m'attends à un problème. Dans ce cas, une erreur n'est pas une exception, c'est l'utilisation prévue.


Renommez l'énumé à quelque chose de moins trompeur au code de l'utilisateur. Vous retournez un statut, pas un code d'erreur. Ensuite, supprimez "Aucun" de l'équation, car il n'y a pas de tel.



15
votes

Puisque vous marquez votre question avec les meilleures pratiques: N'utilisez pas de codes d'erreur lorsque vous pouvez utiliser des exceptions.


9 commentaires

Un autre poste relatif à ce numéro: Exceptions ou codes d'erreur


Vous pouvez utiliser des codes d'exception et d'erreur pour désamorgner et fournir une moyenne pour référencer une erreur spécifique dans la documentation.


Une erreur n'est pas nécessairement une occasion d'une occurrence exceptionnelle. Le code d'erreur peut être la valeur de retour d'une méthode de validation.


Qui a pour dire qu'il n'utiliser pas les codes d'erreur dans une exception?


@Spoulson S'il le fait, il peint des développeurs futurs dans un coin en termes de capable de capturer le type d'exception "le plus spécifique". Le coût de la création d'un insuffisantePermetxception et Connectivitiyerorrexception etc ... n'est pas prohibitif.


@Michael, je recommanderais vraiment de le faire. Imaginez combien de cours d'exception que vous devriez faire face si vous avez créé une exception séparée pour chaque SQL, Win32 ou COM. De plus, vous pouvez utiliser des gestionnaires d'exception filtrés attraper ex comme comexcétion où ex.errorcode = 123456 .


La convention dans la pratique sur cette basebase est que les codes d'erreur sont utilisés pour les défaillances connues, et des exceptions sont utilisées pour des situations que lorsque le traitement ne peut pas continuer. La validation est un exemple parfait. En outre, la question n'avait rien à voir avec des exceptions.


Alors @Bwerks, vous devriez peut-être faire un retardement sur "la moins mauvaise pratique" ...?


La question concerne la Déclaration d'Enums, pas la manière dont ces Enums seront utilisés. L'exemple que j'ai fourni est anecdotique. À moins que vous ne suggérez que l'utilisation d'Enums à quelque fin est toujours une mauvaise pratique, je pense que la balise va bien.



6
votes

à mon avis inconnu ou Aucun signifie la même chose dans le contexte du code énumération. Mon raisonnement est que si je vérifie un code d'erreur que c'est parce que j'ai déjà une erreur.

Je suis également d'avis qu'un énumération de code d'erreur n'est utile que dans une exception personnalisée ou comme des données personnalisées d'un type d'exception existant et des deux scénarios, vous aurez toujours une erreur.


2 commentaires

Cet appel n'est pas à moi, malheureusement; Toutefois, étant donné que ces valeurs seront persistées dans une base de données, il est logique d'inclure inconnu comme moyen de traduire à NULL dans la base de données. Bien que je suppose que l'utilisation d'une nullable dans ce cas fonctionnerait aussi.


Pourquoi l'appel n'est-il pas à vous? Comment modifier les valeurs ENUM si vous n'avez pas accès au code qui attire les exceptions et renvoie les codes d'erreur (pour des erreurs inconnues en particulier)? S'il s'agit d'un problème politique, s'il vous plaît, pour l'amour de la justice et de la vérité et de l'économie d'argent, indiquez les pouvoirs qui se tiennent à ce sujet et à des postes connexes afin qu'ils puissent constater qu'une majorité de développeurs de logiciels professionnels s'opposent fortement aux codes d'erreur de retour!



0
votes

Errorcodesdes Bad. Exceptions bien. Mais pour répondre à la question comme demandé:

si votre énum a une valeur "inconnue", elle devrait être la valeur par défaut.


3 commentaires

Tout d'abord, les codes d'erreur sont souvent combinés avec des exceptions. Deuxièmement, il est poli d'offrir une méthode de validation pour que l'utilisateur puisse voir quelles erreurs se produiraient si la tentative de l'action. Remetber, des exceptions sont chères à la fois dans le temps et les lignes de code CPU.


@Jonathan, je suis d'accord, sauf que avec validation, l'appelerais-tu vraiment "Errorcodes?" De plus, typiquement, la validation se produit à un niveau suffisamment élevé que vous pouvez utiliser des constantes (ou des chaînes localisées) pour représenter l'erreur de validation. Si cela devient suffisamment profondément dans votre cadre pour exiger un code, c'est vraiment est une condition exceptionnelle.


J'avais l'habitude de retourner des cordes, mais cela a fait de la recherche et de filtrer très fort. Nous avons donc maintenant un code d'erreur pour chaque scénario en plus des chaînes. Ce ne sont pas des erreurs d'application non plus, ce sont des problèmes de données qu'un utilisateur d'entreprise doit rechercher et corriger manuellement.



3
votes

Tout d'abord, vous ne devriez pas avoir de code d'erreur Aucun. Appelez-le "Success".

Pensez maintenant à la façon dont vous allez vérifier le code d'erreur. La plupart des gens attendent quelque chose comme ceci: xxx

ou ils utilisent le sténographie xxx

donc là que vous l'avez donc. Votre code de réussite est 0, vous n'avez pas de code de personne et inconnu peut être tout ce que vous voulez.


0 commentaires

0
votes

Idito à tous les "Je ne ferais pas les réponses", mais si vous insistez, voici mon 0,02 $.

errorcodes.none code> n'a aucun sens, car il n'y a aucune erreur. errorcodes.unknown code> n'est pas utile. Essayez de retourner un code d'erreur nullable: p>

var error = DoFoo();
if (error != null)
    // react


1 commentaires

Je ne suis pas d'accord avec ça. Premièrement, FXCOP nous dit que nous devrions toujours avoir une valeur "par défaut" pour quand "l'ENUM n'a pas été explicitement définie". Donc, avoir "inconnu" ou "aucun" est définitivement approprié. Deuxièmement, en utilisant une nullable ou? La syntaxe spermise un point important d'avoir une énumération, de forcer le consommateur à choisir quelque chose!



5
votes

Certainement pas une bonne pratique. Mais s'il n'y a pas d'autre moyen ... alors je passerais généralement à la deuxième option:

public enum ErrorCode 
{ 
    Unknown = -1, 
    None = 0, 
    InsufficientPermissions, 
    ConnectivityError, 
    ... 
} 


1 commentaires

Merci d'avoir répondu à la question basée sur la convention, et de ne pas être distraire à quel point c'est merdique.



4
votes

Je suppose que je suppose que je vais être en désaccord avec tout le monde à ce sujet.

Il n'y a rien de mal avec les codes d'erreur lorsqu'il est utilisé dans le sens de " quel est l'état actuel de cette fonctionnalité. "

Pour constituer un exemple: si vous avez un dossier Temp en réseau optionnel, vous souhaitez accéder et que vous souhaitez afficher les résultats de la dernière fois que vous avez tenté d'y accéder, vous sauveriez cela dans un code d'erreur. Peut-être sur une barre d'état que vous souhaitez afficher l'état actuel à l'utilisateur.

Pour moi, je n'utiliserais aucun comme 0, comme défaut. Je ne vois aucune raison de faire un inconnu être négatif. Inconnu est un état d'erreur parfaitement fin. Vous pouvez simplement le mettre à la fin de la liste. En pratique, j'ai fait xxx

et pour répondre à votre question, je dis aucun ne doit être la valeur par défaut . Aucun signifie: aucune erreur n'existe que vous êtes au courant. Inconnu signifierait pour moi: une erreur existe tellement obscur que vous ne pouvez pas en tenir compte dans votre code.


0 commentaires

1
votes

Je dois réellement être en désaccord avec quiconque dit que vous ne devriez utiliser que des exceptions. Lorsque vous utilisez un type d'application utilisant une base de données, vous pouvez vouloir stocker des statuts pour les données du système. Qu'ils soient des codes d'erreur ou une sorte de statut, ils sont mieux représentés dans la base de données comme entièrement entiers.

L'utilisation et la manutention des exceptions est une compétence très importante et devrait être utilisée, mais je pense que le code d'erreur avec ces exceptions est généralement une bonne idée. Cela ne prend pas trop de ressources supplémentaires et se prête à être utilisée dans une application connectée à la base de données.

Je suggérerais de changer "Aucun" au "succès" comme suggéré, mais que vous faites "succès" une valeur de 1, et que toutes les autres erreurs augmentent de là. La raison derrière ceci est dû au fait que comme une norme dans la plupart des applications de base de données, les colonnes d'état ne sont pas nullables et sont généralement suivies en tant qu'étabeurs. Cela peut conduire à des problèmes si vous utilisez un statut de réussite de 0 car par par défaut, les colonnes entier non nullables seront définies sur 0 si un utilisateur n'entraîne pas explicitement autre chose. Cela conduirait à un faux code d'état / erreur et entraînerait des problèmes dans l'avenir de votre demande. Non seulement cette variables entière est automatiquement initialisée à 0 par défaut dans C #, ce qui l'entraîne d'être un succès automatique, de sorte que vous définissez si vous ne définissez pas la valeur initiale, et ce n'est pas quelque chose que vous voulez.

Également à partir d'un point de vue codant A 1 peut également dire vrai, et il va donc bien avec le succès. Il existe des situations où cela peut ne pas être le cas cependant. Dans les systèmes basés sur UNIX, un retour de 0 signifie succès / aucune erreur, et dans d'autres langues telles que C ++ a 0 Retour est standard à partir de la fonction principale indiquant une exécution réussie de la fonction principale.


0 commentaires