J'ai toujours été d'avis que les propriétés (c'est-à-dire leurs opérations set / get) devraient être rapides / immédiates et sans échec. Vous ne devriez jamais avoir à essayer / attraper pour obtenir ou définir une propriété.
Mais j'examine quelques façons d'appliquer la sécurité basée sur les rôles aux propriétés de certains objets. Par exemple, une propriété Employee.Salary. Certaines des solutions que j'ai rencontrées que d'autres ont essayées (une en particulier est l'exemple AOP ici ) impliquent de lever une exception si l'accesseur n'a pas les bonnes autorisations - mais cela va à l'encontre d'une règle personnelle que j'ai eue depuis longtemps maintenant.
Alors je demande: ai-je tort? Les choses ont-elles changé? Est-il admis que les propriétés devraient pouvoir lever des exceptions?
la source
Réponses:
lorsque vous définissez la valeur d'une propriété, lever une exception sur une valeur non valide est très bien
obtenir la valeur d'une propriété ne devrait (presque) jamais lever d'exception
pour un accès basé sur les rôles, utilisez des interfaces ou des façades différentes / plus stupides; ne laissez pas les gens voir des choses qu'ils ne peuvent pas avoir!
la source
Je considère que c'est surtout une mauvaise forme, mais même Microsoft recommande parfois d'utiliser des exceptions. Un bon exemple est la propriété abstraite Stream.Length . Selon les directives, je serais plus soucieux d'éviter les effets secondaires sur les getters et de limiter les effets secondaires sur les setters.
la source
Je dirais certainement qu'il y a une faille dans la conception si vous ressentez le besoin de lever des exceptions à partir d'un setter de propriété ou d'un getter.
Une propriété est une abstraction qui représente quelque chose qui n'est qu'une valeur . Et vous devriez pouvoir définir une valeur sans craindre que cela ne lève une exception. *
Si la définition de la propriété entraîne un effet secondaire, cela devrait vraiment être implémenté en tant que méthode. Et si cela ne produit aucun effet secondaire, aucune exception ne doit être levée.
Un exemple déjà mentionné dans une réponse différente est la
Stream.Position
propriété. Cela produit des effets secondaires et peut lever des exceptions. Mais cet ensemble de propriétés n'est en fait qu'un wrapperStream.Seek
que vous pourriez appeler à la place.Personnellement, je crois que le poste n'aurait pas dû être une propriété accessible en écriture.
Un autre exemple où vous pourriez être tenté de lever une exception à partir d'un ensemble de propriétés est dans la validation des données:
Mais il existe une meilleure solution à ce problème. Introduisez un type représentant une adresse e-mail valide:
La
Email
classe s'assure qu'elle ne peut pas contenir une valeur qui n'est pas une adresse e-mail valide, et les classes qui ont besoin de stocker des e-mails sont déchargées de l'obligation de les valider.Cela conduit également à une cohésion plus élevée (un indicateur d'une bonne conception logicielle) - la connaissance de ce qu'est une adresse e-mail et de la façon dont elle est validée n'existe que dans la
Email
classe, qui n'a que cette préoccupation.* ObjectDisposedException est la seule exception valide (sans jeu de mots) à laquelle je peux penser en ce moment.
la source
Je sais que votre question est spécifique à .NET , mais comme C # partage un peu d'histoire avec Java, j'ai pensé que cela pourrait vous intéresser. Je suis pas de quelque façon que ce qui implique que parce que quelque chose se fait en Java, il doit être fait en C #. Je sais que les deux sont très différents, en particulier dans la façon dont C # prend en charge les propriétés au niveau du langage. Je donne juste un peu de contexte et de perspective.
De la spécification JavaBeans :
Prenez tout cela avec un grain de sel, s'il vous plaît. La spécification JavaBeans est ancienne et les propriétés C # sont (IMO) une énorme amélioration par rapport aux propriétés basées sur la "convention de dénomination" de Java. J'essaie juste de donner un peu de contexte, c'est tout!
la source
Le point d'une propriété est le principe d'accès uniforme , c'est-à-dire qu'une valeur doit être accessible via la même interface, qu'elle soit implémentée par stockage ou par calcul. Si votre propriété lève une exception qui représente une condition d'erreur indépendante de la volonté du programmeur, du type qui est censé être intercepté et géré, vous obligez votre client à savoir que la valeur est obtenue via le calcul.
D'un autre côté, je ne vois aucun problème à utiliser des assertions ou des exceptions de type assertion qui sont destinées à signaler une utilisation incorrecte de l'API au programmeur plutôt que d'être interceptées et gérées. Dans ces cas, la bonne réponse du point de vue de l'utilisateur de l'API n'est pas de gérer l'exception (se souciant ainsi implicitement de savoir si la valeur est obtenue via le calcul ou le stockage). C'est pour corriger son code afin que l'objet ne se retrouve pas dans un état invalide ou pour vous faire corriger votre code afin que l'assertion ne se déclenche pas.
la source
AFAIK, ces conseils proviennent principalement du processus de réflexion que les propriétés peuvent finir par être utilisées au moment de la conception . (Par exemple, la propriété Text sur un TextBox) Si la propriété lève une exception lorsqu'un concepteur essaie d'y accéder, VS ne va pas passer une bonne journée. Vous obtiendrez un tas d'erreurs juste en essayant d'utiliser le concepteur et pour les concepteurs d'interface utilisateur, ils ne seront pas rendus. Cela s'applique également au temps de débogage, bien que ce que vous verrez dans un scénario d'exception ne soit que "xxx Exception" et qu'il n'encombre pas VS IIRC.
Pour les POCO, cela ne fera pas vraiment de mal, mais je répugne toujours à le faire moi-même. Je pense que les gens voudront accéder aux propriétés plus fréquemment, donc ils devraient normalement être à faible coût. Les propriétés ne devraient pas faire le travail des méthodes, elles devraient juste obtenir / définir des informations et en faire en règle générale.
la source
Bien que beaucoup dépende du contexte, j'éviterais généralement de mettre toute sorte de logique cassable (y compris les exceptions) dans les propriétés. À titre d'exemple, il y a beaucoup de choses que vous (ou une bibliothèque que vous utilisez) pourriez faire qui utilisent la réflexion pour parcourir les propriétés, entraînant des erreurs que vous n'aviez pas prévues au moment de la conception.
Je dis généralement, car il peut y avoir des moments où vous voulez absolument, définitivement, bloquer quelque chose sans trop vous soucier des conséquences. La sécurité, je suppose, serait le cas classique là-bas.
la source