Avoir des constantes publiques est-il «mauvais»?


39

Est-ce:

public MyClass
{
    public const string SomeString = "SomeValue";
}

pire que cela:

public MyClass
{
    public static string SomeString { get{ return "SomeValue";}}
}

Les deux peuvent être référencés de la même manière:

if (someString == MyClass.SomeString)
     ...

La seconde cependant a la protection d'être une propriété. Mais à quel point cela vaut-il mieux qu'un const?

J'ai appris maintes et maintes fois le danger d'avoir des champs publics. Ainsi, lorsque j'ai vu du code utilisant ces constantes sur des champs publics, je me suis immédiatement mis à les refactoriser en propriétés. Mais à mi-parcours, je me suis demandé quel était l'avantage d'avoir les propriétés statiques sur les constantes.

Des idées?


1
Les constantes publiques utilisées de cette manière conviennent parfaitement. Utiliser des propriétés de cette manière est excessif.
Bernard le

2
Avez-vous envisagé d'utiliser le mot clé readonly ? ReadOnly vous donne le syntanx plus propre d'un const sans les problèmes mentionnés dans de nombreux articles.
Matt Raffel

Pourrait aussi faire ... public statique en lecture seule type constantName = 0;
Snoop

Réponses:


57

En C #, c'est très mauvais pour aucune des raisons mentionnées dans ce fil.

Les constantes publiques en C # sont incorporées dans les assemblys de référencement. Cela signifie que si vous avez un SomeOtherClass dans un assemblage séparé référençant SomeString dans MyClass, le CIL généré pour SomeOtherClass contiendra une chaîne "SomeValue" codée en dur.

Si vous allez redéployer la dll contenant MyClass mais pas SomeOtherClass et que vous modifiez le paramètre const, SomeOtherClass ne contiendra pas ce que vous pensez, il contiendra la valeur d'origine.

Si vous êtes 100% positif, c'est une constante universelle comme Pi, devenez fou; sinon marchez prudemment.

Voici une meilleure explication: https://stackoverflow.com/questions/55984/what-is-the-difference-between-const-and-readonly


3
@Oded, mais la même différence se situe entre constune propriété en lecture seule. constest cuit dans l'assembly appelant, la propriété en lecture seule ne l'est pas.
svick le

1
C'est quelque chose que je ne savais pas. C'est une autre preuve que les champs publics sont mauvais. Je pense que même l'exemple "sûr" de Pi est une mauvaise idée (Qu'en est-il lorsqu'un développeur veut plus ou moins de chiffres de précision sur Pi? Et apporte la modification à l'assemblage sans connaître ce problème.) J'ai plus de 40 assemblages dans mon solution et je pouvais voir cela vraiment nous mordre si nous ne faisons pas attention.
Vaccano

2
Cette "copie" se produit-elle dans d'autres parties de C #? (ie enums)
Vaccano

2
Oui, la copie arrive. Ce n'est généralement pas un problème, mais si votre code utilise la valeur numérique d'un Enum et qu'il est modifié de la manière décrite dans cette question, cela peut poser problème.
Vaccano

1
C'est l'une des principales raisons pour lesquelles consten C # est stupide. Nous avons besoin d'un meilleur support pour les immuables ...
KChaloux

22

Changer un champ dans une propriété est un changement radical. Vous perdez la compatibilité binaire, source et réflexion.

En plus:

  • Il existe un contrôle d’accès plus fin avec les propriétés. Avez-vous besoin d'être publiquement accessible, mais ne voulez-vous vraiment que l'accès à un accès protégé? Pas de problème (à partir de C # 2, au moins).
  • Voulez-vous pénétrer dans le débogueur chaque fois que la valeur change? Il suffit d'ajouter un point d'arrêt dans le setter.
  • Voulez-vous vous connecter tous les accès? Ajoutez simplement la journalisation au getter.
  • Les propriétés sont utilisées pour la liaison de données; les champs ne sont pas.

http://csharpindepth.com/articles/chapter8/propertiesmatter.aspx

Cela dit, je ne vois pas en quoi les constantes sont vraiment affectées par cette situation (surtout si vous n’avez besoin d’aucune des fonctionnalités ci-dessus), à moins que votre API ne change de telle sorte qu’elles ne soient plus des constantes.


11

Les dangers des champs publics résident dans le fait qu'ils sont mutables et que leur mise en œuvre est susceptible de changer.

En règle générale, il constne s'agit pas d'un problème (comme pour les énumérations publiques) - à moins que vous ne pensiez que le résultat constfinirait par devenir mutable et que vous aurez besoin d'encapsulation à un moment donné autour de l'accesseur (par exemple, pour consigner le nombre de fois où il a été regardé up), vous pourriez aussi bien le garder en public const.


1

Une constante est les données. Les propriétés impliquent la possibilité de comportement lorsque vous "regardez" la valeur.

Le comportement de regroupement (ou la possibilité future de celui-ci) avec des données constantes est totalement faux. Pour la plupart des systèmes, ce n'est pas grave, mais c'est possible.

Disons que la valeur est "PI" et largement utilisée dans les calculs du système. Le fait de le placer derrière des propriétés forcera les programmeurs clients à programmer de manière défensive. Ils doivent affecter la valeur à une constante en double. S'ils ne dupliquent pas, la bibliothèque pourrait avoir un "comportement" indésirable introduit derrière la propriété dans la prochaine version. Le comportement de la propriété (s'il s'agit d'une bibliothèque compilée) est inconnu. Peut-être que cela fonctionne bien en test, mais il pourrait y avoir du code caché qui s'exécute si une condition spéciale est remplie. Ce n'est pas une optimisation pré-mature. Surtout pour un système en temps réel, la vie des personnes dépend.

Les programmeurs clients peuvent même perdre la sécurité d'une constante car le langage peut ne pas leur permettre d'affecter une valeur de propriété à leur constante de duplication.

En outre, lorsque les programmeurs sont obligés d'affecter la valeur de votre propriété à leur propre constante, ils annulent en réalité le comportement que vous espériez obtenir avec votre propriété.

Les vraies données constantes n'ont pas besoin ou ne veulent pas d'encapsulation.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.