Il semble y avoir trois choix pour la mise en œuvre de constantes accessibles au public en C #. Je suis curieux s'il y a de bonnes raisons de choisir l'un sur l'autre ou si c'est juste une question de préférence personnelle.
Choix 1 fort> - Champ privé plus Getter Getter P> public const string SomeConstant = "string that will never change";
6 Réponses :
considérer raison: lorsque vous exposez (puis consommez ailleurs) a A const code>, le
const code> est intégré dans la consommation Les métadonnées de type. P>
Public statique réadonny code> n'est pas, et puisqu'il est
Statique Readonly code>, il ne vous coûte que pour l'instanciation une fois, et il est immuable comme un
const code>. p> p>
Le const n'est pas intégré dans les métadonnées. Le problème est que la valeur littérale du const est intégrée à l'IL.
C'est un problème pour la compilation séparée. Si vous modifiez la définition de la constante, vous devrez recompiler (par opposition à simplement recharger / re-JIT) des assemblages à charge.
Le bon choix est le choix n ° 4:
public static readonly string SomeConstant = "string that might change in a new version";
Y a-t-il une raison pour laquelle je ne pouvais pas / ne devrait pas changer la valeur d'un const code> dans une nouvelle version? Je l'ai certainement fait auparavant sans remarquer aucune conséquence négative.
Oui il y a. La valeur littérale d'un const est intégrée à l'IL. Vous rencontrez de gros problèmes lorsque vous ne reculez qu'une seule bibliothèque (par exemple, pour une solution de bogue). D'autres assemblages utilisant le const couriront toujours avec l'ancienne valeur. Un const doit toujours être déclaré privé pour que cela ne puisse jamais arriver.
Hans, bien alors pourquoi ne pas aller avec le choix n ° 1? Le const est déclaré privé. Et pourquoi statique est-elle nécessairement souhaitable? Peut-être que j'aimerais accéder à la valeur const code> via une instance de la classe pour permettre le polymorphisme.
Pas d'argument avec ça, mais pourquoi écrire 5 lignes de code quand je ferai?
HAN, également, si vous tapez cinq lignes de code est un problème, qu'est-ce qui ne va pas avec le choix n ° 2?
Je ne pense pas que personne considère une propriété virtuelle une «constante polymorphe». Appelez cela une propriété. Le motif est commun.
Hans, c'est un point juste, mais tout ce que vous l'appelez, le choix n ° 2 est relativement compact, permet au polymorphisme et n'a pas de problème avec les valeurs qui se sont écrites dans l'IL. Êtes-vous d'accord?
HM, eh bien, en théorie, je dirais qu'un const code> ne devrait pas changer, même dans les prochains versions. En pratique, cela est bien sûr une autre affaire (est une version variable
code> Cons par exemple). (Philosophiquement, je suppose que rien n'est constant. :-))
const code> Les membres sont membres de la classe, non membres d'instance (en d'autres termes,
const code> implique
statique code>). p>
Les choix 1 et 2 sont équivalents, vraiment. P>
Il me semble qu'il y a vraiment trois situations différentes: p>
Vous savez pour certain que la chaîne ne changera jamais. Dans ce cas, il est raisonnable de le faire Vous pensez que la chaîne pourrait changer à l'avenir, mais vous savez que ce sera toujours une constante dans une version unique. Dans ce cas, un champ "CODE> STATIC STATIQUE PUBLICY CODE> est correct. N'oubliez pas que cela va bien de le faire avec des chaînes comme elles sont immuables, mais vous ne devriez pas le faire avec des types mutables tels que des tableaux. (Exposez-vous à des collections immuables ou utilisez une propriété et renvoyez une nouvelle copie à chaque fois.) P> li>
Vous pensez que la chaîne pourrait changer, et cela pourrait même changer dans la durée de vie d'un programme ... Par exemple, "La date actuelle, formatée". Dans ce cas, utilisez une propriété en lecture seule em> (une avec seulement un getter). Notez que changer d'un champ lisonly à une propriété en lecture seule est un changement source em> -Compatible, mais pas un Binary em> modification compatible - donc si vous avez plongé pour ma seconde Bullet, mais il faut ensuite passer à la troisième, vous devez tout recompiler. P> LI>
ul> const code>. (Par exemple,
math.pi code> est Const. Cela ne changera pas de temps bientôt.) Il y a des implications de mémoire subtiles à ce que cela soit sur l'utilisation de
statique loadonly code>, mais ils 'Re très peu susceptible de vous affecter. Vous ne devriez pas faire cela si la valeur peut changer et em> vous ne voulez pas recompiler tous les appelants dans cette situation, pour les raisons données ailleurs. Notez que pour de nombreux projets (en particulier les entreprises internes), ce n'est vraiment pas un problème de recompiler tous les appelants. P> Li>
Hmm, je viens d'essayer votre troisième option, mais je reçois "le modificateur lisonly code> n'est pas valide pour cet élément. Le code fautif était:
STATINAL STATIQUE SOCONSTANT {GET {RETURNE" Quelqu'un "}}} code>. Voulez-vous dire juste
Static public code>?
En rétrospectivement, je pense que vous devez simplement vouloir dire "readonly" dans le sens de "a un getter seulement, pas de setter", et non d'essayer littéralement de marquer la propriété readonly code> :)
Si je pouvais voter - je voterais la réponse de Jon Skeet. Pour y ajouter, votre n ° 1 et N ° 2 sont exactement identiques, comme indiqué ici dans IL:
.field public static literal string SomeConstant = "string that will never change"
Une propriété semble vraiment être le meilleur choix car la chaîne code> renvoyée code> n'est pas intégrée dans les métadonnées. const code> est vraiment destiné à une utilisation interne (par exemple, un numéro de version peut être effectué dans un
const code> et pourrait changer) ou pour les valeurs qui ne changeront absolument jamais aussi loin comme le code qui référence est concerné. p>
Si vous utilisez Visual Studio, il possède un mécanisme existant qui générera automatiquement des propriétés pour vous: fichiers de ressources. Il fait fondamentalement l'option 1 automatiquement. Notez également que si vous souhaitez toujours prendre en charge plusieurs langues, il existe également des mécanismes spéciaux. Le premier étant que vous définissez vos constantes dans un assemblage satellite.