Est-il possible d'écrire quelque chose de similaire au suivant?
public const string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
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'initialiseur de tableau que vous avez montré n'est pas une expression constante en C #, il génère donc une erreur du compilateur.
La déclarer readonly
résout ce problème car la valeur n'est initialisée qu'à l'exécution (bien qu'il soit garanti qu'elle ait été 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 };
Vous pouvez déclarer un tableau en tant que readonly
, mais n'oubliez pas que vous pouvez changer l'élément de readonly
tableau.
public readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
...
Titles[0] = "bla";
Pensez à utiliser enum, comme suggéré par Cody, ou IList.
public readonly IList<string> ITitles = new List<string> {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
Vous ne pouvez pas créer de tableau 'const' car les tableaux sont des objets et ne peuvent être créés qu'au moment de l'exécution et 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 "en lecture seule". Cela a le même effet que const, sauf que la valeur peut être définie au moment de l'exécution. Il ne peut être défini qu’une fois, puis il s’agit d’une valeur en lecture seule (c’est-à-dire const).
Depuis le n ° 6, vous pouvez l'écrire comme ceci:
public static string[] Titles => new string[] { "German", "Spanish", "Corrects", "Wrongs" };
Voir aussi: C #: Le C 6.0 nouveau et amélioré (plus précisément le chapitre "Propriétés et propriétés associées à l'expression")
Cela créera une propriété statique en lecture seule, mais vous permettra quand même de modifier le contenu du tableau renvoyé, mais lorsque vous appelez à nouveau la propriété, vous obtenez à nouveau le tableau d'origine non modifié.
Pour clarifier, ce code est le même que (ou en réalité un raccourci pour):
public static string[] Titles
{
get { return new string[] { "German", "Spanish", "Corrects", "Wrongs" }; }
}
Veuillez noter que cette approche présente des inconvénients: Un nouveau tableau est en fait instancié sur chaque référence. Par conséquent, si vous utilisez un très grand tableau, cela risque de ne pas être la solution la plus efficace. Mais si vous réutilisez le même tableau (en le plaçant par exemple dans un attribut privé), vous aurez de nouveau la possibilité de changer le contenu du tableau.
Si vous voulez avoir un tableau immuable (ou une liste), vous pouvez aussi utiliser:
public static IReadOnlyList<string> Titles { get; } = new string[] { "German", "Spanish", "Corrects", "Wrongs" };
Cependant, cela comporte toujours un risque de modification, car vous pouvez toujours le reconvertir en chaîne [] et modifier le contenu, en tant que tel:
((string[]) Titles)[1] = "French";
Vous pouvez adopter une approche différente: définissez une chaîne constante pour représenter votre tableau, puis divisez-la en un tableau lorsque vous en avez besoin, par exemple.
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 si nécessaire.
Alastair
Si vous déclarez un tableau derrière une interface IReadOnlyList, vous obtenez un tableau constant avec des valeurs constantes déclaré à l'exécution:
public readonly IReadOnlyList<string> Titles = new [] {"German", "Spanish", "Corrects", "Wrongs" };
Disponible dans .NET 4.5 et supérieur.
A . NET Framework v4.5 + solution qui améliore la version réponse de tdbeckett :
_using System.Collections.ObjectModel;
// ...
public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
new string[] { "German", "Spanish", "Corrects", "Wrongs" }
);
_
Remarque: étant donné que la collection est conceptuellement constante, il peut être judicieux de définir static
pour la déclarer au niveau de la classe .
Ce qui précède:
Initialise le champ de sauvegarde implicite de la propriété une fois avec le tableau.
Notez que _{ get; }
_ - c’est-à-dire ne déclarer qu’une propriété getter - est ce qui rend la propriété elle-même implicitement en lecture seule (en essayant de combiner readonly
avec _{ get; }
_ est en fait une erreur de syntaxe).
Sinon, vous pouvez simplement omettre le _{ get; }
_ et ajouter readonly
pour créer un champ à la place d'une propriété, comme dans la question, mais en exposant public données membres en tant que propriétés plutôt que des champs est une bonne habitude à former.
Crée un tableau - semblable à (permettant un accès indexé ) c'est-à-dire réellement et robustement en lecture seule (conceptuellement constant, une fois créé), les deux en ce qui concerne:
IReadOnlyList<T>
solution, où un _(string[])
_ cast peut être utilisé pour obtenir un accès en écriture aux éléments , comme indiqué dans tile de mjepsen réponse .IReadOnlyCollection<T>
_ , qui, malgré la similitude de nom avec , la classe ReadOnlyCollection
, ne supporte même pas indexée access , ce qui le rend fondamentalement inapproprié pour fournir un accès semblable à un tableau.)Pour mes besoins, je définis static
tableau, au lieu de impossible const
et cela fonctionne: public static string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
C'est une façon de faire ce que tu veux:
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
public ReadOnlyCollection<string> Titles { get { return new List<string> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}}
Cela ressemble beaucoup à faire un tableau en lecture seule.
Par souci d’exhaustivité, nous disposons maintenant également de ImmutableArrays. Cela devrait être vraiment immuable:
public readonly static ImmutableArray<string> Tiles = ImmutableArray.Create(new[] { "German", "Spanish", "Corrects", "Wrongs" });
Requiert une référence System.Collections.Immutable NuGet
https://msdn.Microsoft.com/en-us/library/mt452182 (v = vs.111) .aspx
Je crois que vous ne pouvez le faire qu'en lecture seule.
Les tableaux sont probablement l'une de ces choses qui ne peuvent être évaluées qu'au moment de l'exécution. Les constantes doivent être évaluées au moment de la compilation. Essayez d'utiliser "readonly" au lieu de "const".
Au lieu de cela, pour contourner le problème elements-can-be-be-modified avec un tableau en lecture seule, vous pouvez utiliser une propriété statique à la place. (Les éléments individuels peuvent toujours être modifiés, mais ces modifications ne seront effectuées que sur la copie locale du tableau.)
public static string[] Titles
{
get
{
return new string[] { "German", "Spanish", "Corrects", "Wrongs"};
}
}
Bien sûr, cela ne sera pas particulièrement efficace car un nouveau tableau de chaînes est créé à chaque fois.