2009-11-12 6 views
81

J'ai différentes constantes que mon programme utilise ... string, int, double, etc ... Quelle est la meilleure façon de les stocker? Je ne pense pas que je veux un Enum, parce que les données ne sont pas toutes du même type, et je veux définir manuellement chaque valeur. Dois-je les stocker tous dans une classe vide? Ou y a-t-il un meilleur moyen?Quelle est la meilleure façon de stocker un groupe de constantes que mon programme utilise?

+15

De la façon dont vous le souhaitez, comme vous en avez besoin. –

Répondre

107

Vous pourriez probablement les avoir dans une classe statique, avec des propriétés statiques en lecture seule.

public static class Constants 
{ 
    public static string SomeConstant { get { return "Some value"; } } 
} 
+1

Grrr .. 40 secondes plus rapide sur le tirage au sort :) –

+21

+1, mais encore mieux si vous pouvez tirer ces à partir d'un fichier de ressources pour la localisation. –

+16

Semble un peu verbeux - pourquoi pas des chaînes statiques en lecture seule? – emptyset

23

IMO utilisant une classe pleine de constantes est bien pour les constantes. Si elles changent semi-occasionnellement, je recommande d'utiliser AppSettings dans votre config et la classe ConfigurationManager à la place.

Lorsque j'ai des "constantes" qui sont réellement tirées depuis AppSettings ou similaires, j'ai toujours une classe "constantes" qui enveloppe la lecture du gestionnaire de configuration. Il est toujours plus significatif d'avoir Constants.SomeModule.Setting au lieu d'avoir à recourir directement à ConfigurationManager.AppSettings["SomeModule/Setting"] sur n'importe quel endroit qui veut consommer ladite valeur de réglage.

points bonus pour cette configuration, car SomeModule serait probablement une classe imbriquée dans le fichier Constantes, vous pouvez facilement utiliser l'injection de dépendances pour injecter soit SomeModule directement dans les classes qui en dépendent. Vous pouvez même extraire une interface au-dessus de SomeModule puis créer une dépendance à ISomeModuleConfiguration dans votre code consommateur, cela vous permettra alors de découpler la dépendance aux fichiers de constantes, et même de rendre le test plus facile, surtout si ces paramètres proviennent de AppSettings et vous les modifiez à l'aide de transformations de configuration car les paramètres sont spécifiques à l'environnement.

+1

Juste pour ajouter à ceci: la raison est que lorsque vous construisez, les constantes utilisées d'autres assemblées ne sont pas mises à jour. Cela signifie que si vous avez AssemblyA et AssemblyB et B utilise une constante de A, la valeur est copiée, pas référencée, donc la reconstruction A ne mettra pas à jour B. Cela peut conduire à des bogues bizarres. –

+1

@CamiloMartin Beaucoup de façons de gérer cela, vos "constantes" pourraient être statiques readonlys pour éviter cela, ou comme je le disais si elles changent plus d'une fois dans une lune bleue pour utiliser le ConfigurationManager. –

+0

Oui, je disais juste que ce n'est pas seulement parce que c'est une convention que vous devriez utiliser la lecture statique, mais parce que cela peut être une source de confusion. En outre, une alternative à ConfigurationManager est les fichiers de ressources - il vous suffit d'ajouter un autre fichier de ressources avec un code de langue dans le nom et votre code est instantanément localisé. –

17

Ce que je veux faire est la suivante (mais assurez-vous de lire à la fin d'utiliser le bon type de constantes):

internal static class ColumnKeys 
{ 
    internal const string Date = "Date"; 
    internal const string Value = "Value"; 
    ... 
} 

Read this savoir pourquoi const pourrait ne pas être ce que tu veux. Possible type de constantes sont:

  • const champs. Ne pas utiliser entre les assemblys (public ou protected) si la valeur pourrait changer à l'avenir car la valeur sera codée en dur au moment de la compilation dans ces autres assemblys. Si vous modifiez la valeur, l'ancienne valeur sera utilisée par les autres assemblys jusqu'à ce qu'ils soient recompilés.
  • static readonly champs
  • static propriété sans set
+1

Pourquoi readonly si utilisé sur plusieurs assemblages? –

+0

Pourquoi la lecture statique fonctionne-t-elle mieux avec plusieurs assemblages qu'avec const? –

+13

Les valeurs const sont copiées de l'assembly source dans le code compilé. Cela signifie que si vous devez changer une valeur const, tous les assemblages dépendants DOIVENT être recompilés avec la nouvelle version. Plus sûr et plus pratique d'utiliser des readonly statiques. – cfeduke

4

Une classe statique vide est appropriée. Pensez à utiliser plusieurs classes, de sorte que vous vous retrouviez avec de bons groupes de constantes, et pas un seul fichier géant Globals.cs.

De plus, pour certaines constantes int, considérer la notation:

[Flags] 
enum Foo 
{ 
} 

Comme cela permet treating the values like flags.

+0

"Pensez à utiliser plusieurs classes, afin de vous retrouver avec de bons groupes de constantes connexes, et pas un fichier géant Globals.cs." Je crois que c'est la meilleure recommandation, n'y at-il pas des modèles de conception autour de cela? Je ne connais aucun nom, n'est-ce pas? –

1

Oui, un static class pour stocker des constantes serait très bien, sauf pour les constantes qui sont liées à des types spécifiques.

+0

c'est exactement ce que j'essaie de faire. Je veux qu'ils apparaissent en tant que membres de la classe pour laquelle ils sont. mais je ne veux pas les ajouter aux cours parce que les constantes varient en fonction de l'entreprise pour laquelle je travaille. Je n'ai encore rien trouvé sur les constantes d'extension ou les propriétés. mais je pourrais abandonner cette idée parce que je ne veux pas qu'ils apparaissent en tant que membres quand je sérialise ces classes – symbiont

3

Un autre vote pour l'utilisation de web.config ou app.config. Les fichiers de configuration sont un bon endroit pour les constantes comme les chaînes de connexion, etc. Je préfère ne pas avoir à regarder la source pour voir ou modifier ce genre de choses. Une classe statique qui lit ces constantes à partir d'un fichier .config peut être un bon compromis, car elle permettra à votre application d'accéder à ces ressources comme si elles étaient définies dans le code, tout en vous offrant la possibilité de les afficher facilement. espace.

+2

Une chaîne de connexion n'est pas une constante, c'est un paramètre. Il se pourrait que l'OP * signifie vraiment aussi des paramètres, plutôt que des constantes, mais je n'en vois aucune preuve. –

+0

Je ne suis pas d'accord. Les littéraux de chaîne sont des constantes par définition. Changer la chaîne dans un fichier de configuration équivaut à peu près à la changer dans le code et à la recompiler; cela * ne ferait-il pas une constante? Je ne pense pas. –

+2

@David - Pas vrai. Un compilateur ne se soucie pas de la valeur que vous avez dans votre fichier de configuration - ceci est lu lors de l'exécution. –

8

Ceci est la meilleure façon IMO. Pas besoin de propriétés, ou en lecture seule:

public static class Constants 
{ 
    public const string SomeConstant = "Some value"; 
} 
+8

Si vous utilisez const, exposez uniquement en interne. Ne faites pas de const public (même si vous pensez que vos assemblys ne seront pas utilisés à l'extérieur de votre organisation). De plus, les propriétés vous offrent une flexibilité programmatique pour une future expansion sans avoir besoin de redéfinir votre interface. – cfeduke

0

Si ces Constantes sont des références de service ou des interrupteurs cet effet, le comportement de l'application je les mis en place en tant que paramètres utilisateur de l'application. Ainsi, s'ils doivent être modifiés, vous n'avez pas besoin de les recompiler et vous pouvez toujours les référencer via la classe des propriétés statiques.

Properties.Settings.Default.ServiceRef 
-1

Je suggère la classe statique avec readonly statique. Veuillez trouver l'extrait de code ci-dessous:

public static class CachedKeysManager 
    { 
     public static readonly string DistributorList = "distributorList"; 
    } 
Questions connexes