Déclarez un tableau const

Est-il possible d’écrire quelque chose de similaire à ce qui suit?

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

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

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

La raison en est que const ne peut être appliqué qu’à un champ dont la valeur est connue à 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 de compilation.

Le déclarer en 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 }; 

Vous pouvez déclarer le tableau en readonly , mais gardez à l’esprit que vous pouvez modifier l’élément du tableau readonly .

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

Pensez à utiliser enum, comme suggéré par Cody, ou IList.

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

Vous ne pouvez pas créer un tableau ‘const’ car les tableaux sont des objects et ne peuvent être créés qu’à 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 à l’exécution. Il ne peut être défini qu’une seule fois et il s’agit par la suite d’une valeur en lecture seule (c.-à-d. Const).

Pour mes besoins, je définis static tableau static , au lieu de const impossible et cela fonctionne: public static ssortingng[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };

Vous pouvez adopter une approche différente: définir une chaîne constante pour représenter votre tableau, puis diviser la chaîne en un tableau lorsque vous en avez besoin, par exemple

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

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

Alastair

Depuis C # 6, vous pouvez l’écrire comme:

 public static ssortingng[] Titles => new ssortingng[] { "German", "Spanish", "Corrects", "Wrongs" }; 

Voir aussi: C #: le nouveau et le meilleur C # 6.0 (en particulier le chapitre “Fonctions et propriétés liées à l’expression”)

Cela fera une propriété statique en lecture seule, mais vous permettra toujours de modifier le contenu du tableau renvoyé, mais lorsque vous appelez à nouveau la propriété, vous obtiendrez à nouveau le tableau d’origine non modifié.

Pour plus de précision, ce code est le même que (ou en fait un raccourci pour):

 public static ssortingng[] Titles { get { return new ssortingng[] { "German", "Spanish", "Corrects", "Wrongs" }; } } 

Veuillez noter que cette approche présente un inconvénient: un nouveau tableau est en réalité instancié sur chaque référence. Par conséquent, si vous utilisez un très grand tableau, cela pourrait ne pas être la solution la plus efficace. Mais si vous réutilisez le même tableau (en le mettant dans un atsortingbut privé par exemple), cela ouvrira de nouveau la possibilité de modifier le contenu du tableau.

Si vous voulez avoir un tableau immuable (ou une liste), vous pouvez également utiliser:

 public static IReadOnlyList Titles { get; } = new ssortingng[] { "German", "Spanish", "Corrects", "Wrongs" }; 

Mais, cela présente toujours un risque de modifications, car vous pouvez toujours le convertir en chaîne de caractères [] et modifier le contenu, en tant que tel:

 ((ssortingng[]) Titles)[1] = "French"; 

C’est un moyen de faire ce que vous voulez:

 using System; using System.Collections.ObjectModel; using System.Collections.Generic; public ReadOnlyCollection Titles { get { return new List { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}} 

C’est très similaire à faire un tableau en lecture seule.

Une solution .NET Framework v4.5 + qui améliore la réponse de tdbeckett :

 using System.Collections.ObjectModel; // ... public ReadOnlyCollection Titles { get; } = new ReadOnlyCollection( new ssortingng[] { "German", "Spanish", "Corrects", "Wrongs" } ); 

Remarque: Étant donné que la collection est conceptuellement constante, il peut être judicieux de la rendre static pour la déclarer au niveau de la classe .

Ce qui précède:

  • Initialise le champ de support implicite de la propriété une fois avec le tableau.

    • Notez que { get; } { get; } – c’est-à-dire ne déclarer qu’un object getter – est ce qui rend implicitement la propriété read-only (essayer de combiner readonly avec { get; } est en fait une erreur de syntaxe).

    • Alternativement, vous pouvez simplement omettre le { get; } { get; } et ajoutez readonly pour créer un champ au lieu d’une propriété, comme dans la question, mais exposer les membres de données publiques comme des propriétés plutôt que des champs est une bonne habitude à former.

  • Crée une structure de type tableau (permettant un access indexé) qui soit véritablement et solidement en lecture seule (conceptuellement, constante, une fois créée), les deux en ce qui concerne:

    • empêcher la modification de la collection (par exemple en supprimant ou en ajoutant des éléments, ou en remplaçant la collection dans son ensemble)
    • empêcher la modification des éléments individuels.
      (Même la modification indirecte n’est pas possible, contrairement à une IReadOnlyList , où un cast (ssortingng[]) peut être utilisé pour obtenir un access en écriture aux éléments, comme le montre la réponse utile de mjepsen .
      La même vulnérabilité s’applique à l’ IReadOnlyCollection qui, malgré sa similarité avec la classe ReadOnlyCollection , ne prend même pas en charge l’access indexé , la rendant fondamentalement impropre à fournir un access de type tableau.

Si vous déclarez un tableau derrière une interface IReadOnlyList, vous obtenez un tableau constant avec des valeurs constantes qui sont déclarées à l’exécution:

 public readonly IReadOnlyList Titles = new [] {"German", "Spanish", "Corrects", "Wrongs" }; 

Disponible en .NET 4.5 et supérieur.

Je crois que vous ne pouvez que le faire en lecture seule.

Les tableaux sont probablement l’un de ceux qui ne peuvent être évalués 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”.

Comme alternative, pour contourner le problème des éléments pouvant être modifiés 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 ssortingng[] Titles { get { return new ssortingng[] { "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.

Par souci d’exhaustivité, nous avons maintenant aussi ImmutableArrays à notre disposition. Cela devrait être vraiment immuable:

 public readonly static ImmutableArray Tiles = ImmutableArray.Create(new[] { "German", "Spanish", "Corrects", "Wrongs" }); 

Nécessite la référence System.Collections.Immutable NuGet

https://msdn.microsoft.com/en-us/library/mt452182(v=vs.111).aspx