523 votes

Déclarer un tableau const

Est-il possible d'écrire quelque chose de semblable à ce qui suit ?

public const string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };

0 votes

Static pourrait être utilisé, public static string[] Titles = new string[] { "German", "Spanish"} ;

786voto

Cody Gray Points 102261

Oui, mais vous devez le déclarer readonly au lieu de const :

public static readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };

La raison en est que const ne peut être appliqué qu'à un champ dont la valeur est connue au moment de la compilation. L'initialisateur de tableau que vous avez montré n'est pas une expression constante en C#, il produit donc une erreur de compilation.

La déclarer readonly résout ce problème car la valeur n'est pas initialisée avant l'exécution (bien qu'il soit garanti qu'elle soit initialisée avant la première utilisation du tableau).

En fonction de ce que vous souhaitez réaliser, vous pouvez également envisager de déclarer une énumération :

public enum Titles { German, Spanish, Corrects, Wrongs };

126 votes

Notez que le tableau n'est pas en lecture seule, bien sûr ; Titles[2]="Welsh" ; fonctionnerait très bien au moment de l'exécution.

49 votes

Vous voulez probablement qu'il soit statique aussi

4 votes

Pourquoi ne pas déclarer un tableau "const" dans le corps d'une méthode et non dans celui de la classe ?

67voto

Branimir Points 1971

Vous pouvez déclarer un tableau comme readonly mais gardez à l'esprit que vous pouvez changer l'élément de readonly le tableau.

public readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
...
Titles[0] = "bla";

Envisagez d'utiliser un enum, comme l'a suggéré Cody, ou IList.

public readonly IList<string> ITitles = new List<string> {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();

36 votes

Dans .NET 4.5 et plus, vous pouvez déclarer une liste comme IReadOnlyList<string> au lieu de IList<string>.

2 votes

Pour être clair, vous pouvez toujours modifier les valeurs d'une IReadOnlyList (mais pas ajouter ou supprimer des éléments). Mais oui, il serait préférable de la déclarer comme une IReadOnlyList plutôt qu'une IList.

65voto

JAiro Points 2587

Vous ne pouvez pas créer un tableau 'const' parce que les tableaux sont des objets et peuvent seulement être créés au moment de l'exécution, alors que les entités const sont résolues au moment de la compilation.

Ce que vous pouvez faire à la place est de déclarer votre tableau comme étant "readonly". Cela a le même effet que const, sauf que la valeur peut être définie au moment de l'exécution. Elle ne peut être Elle ne peut être définie qu'une seule fois et devient alors une valeur en lecture seule (c'est-à-dire constante).

3 votes

Cet article explique pourquoi les tableaux ne peuvent pas être déclarés comme des constantes.

4 votes

Il est possible de déclarer un tableau constant ; le problème est de l'initialiser avec une valeur constante. Le seul exemple fonctionnel qui me vient à l'esprit est const int[] a = null; qui n'est pas très utile, mais qui est bien une instance d'une constante de tableau.

9voto

Alastair Points 51

Vous pourriez adopter une approche différente : définir une chaîne constante pour représenter votre tableau et ensuite diviser la chaîne en un tableau lorsque vous en avez besoin, par ex.

const string DefaultDistances = "5,10,15,20,25,30,40,50";
public static readonly string[] distances = DefaultDistances.Split(',');

Cette approche vous donne une constante qui peut être stockée dans la configuration et convertie en tableau lorsque cela est nécessaire.

12 votes

Je pense que le coût de l'exécution du fractionnement dépasse de loin les avantages tirés de la définition de la constante. Mais +1 pour une approche unique et une réflexion hors des sentiers battus ;)

1 votes

J'étais sur le point de poster la même solution et puis j'ai vu ceci, contrairement aux remarques dures et négatives, c'était en fait parfait pour mon scénario, où j'avais besoin de passer une constante à un attribut, et ensuite j'ai divisé la valeur dans le constructeur d'attribut pour obtenir ce dont j'avais besoin. et je ne vois pas pourquoi cela aura un coût de performance puisque les attributs ne sont pas créés pour chaque instance.

5voto

ALZ Points 679

Pour mes besoins, je définis static au lieu de l'impossible const et ça marche : public static string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };

1 votes

Il suffit de retirer const de l'exemple OP fonctionne également, mais cela (ou votre réponse) permet de changer les deux : Titles et toute valeur. Quel est donc l'intérêt de cette réponse ?

0 votes

@Sinatr, j'ai répondu à cette question il y a 3 ans, lorsque j'ai commencé à travailler en C#. Je l'ai quitté, maintenant je suis dans le monde Java. J'ai peut-être oublié d'ajouter readonly

1 votes

Après réflexion, votre réponse est directe comment faire fonctionner le code OP sans aucune const / readonly des considérations, simplement le faire fonctionner (comme si const était une erreur de syntaxe). Pour certaines personnes, il semble que ce soit un précieux réponse (peut-être ont-ils également essayé d'utiliser const par erreur ?).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X