651 Stimmen

Ein Konst-Array deklarieren

Ist es möglich, etwas Ähnliches wie das Folgende zu schreiben?

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

0 Stimmen

Static verwendet werden könnte, public static string[] Titles = new string[] {"Deutsch", "Spanisch"};

13voto

mklement0 Punkte 303096

A .NET Framework v4.5+ Lösung die besser ist als tdbecketts Antwort :

using System.Collections.ObjectModel;

// ...

public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
  new string[] { "German", "Spanish", "Corrects", "Wrongs" }
);

Hinweis: Da die Sammlung konzeptionell konstant ist, kann es sinnvoll sein, sie zu static zu erklären, dass sie bei der Klasse Ebene.

Die oben genannten:

  • Initialisiert das implizite Unterstützungsfeld der Eigenschaft einmal mit dem Array.

    • Beachten Sie, dass { get; } - d.h., nur eine Eigenschaft zu deklarieren getter - ist das, was die Eigenschaft selbst implizit schreibgeschützt macht (der Versuch, die readonly con { get; } ist eigentlich ein Syntaxfehler).

    • Alternativ können Sie auch einfach die { get; } und hinzufügen readonly zur Erstellung einer Feld anstelle einer Eigenschaft, wie in der Frage, aber das Aufdecken öffentlich Datenelemente als Eigenschaften und nicht als Felder zu bezeichnen, ist eine gute Angewohnheit, die man sich angewöhnen sollte.

  • Erzeugt eine Array- wie Struktur (erlaubt indizierter Zugang ), das ist wirklich und zuverlässig schreibgeschützt (konzeptionell konstant, einmal geschaffen), sowohl in Bezug auf:

    • Verhinderung von Änderungen an der Sammlung in seiner Gesamtheit (z. B. durch Entfernen oder Hinzufügen von Elementen oder durch Zuweisung einer neuen Sammlung an die Variable).
    • Verhinderung der Änderung von einzelne Elemente .
      (Auch indirekt Änderung nicht möglich ist - anders als bei einer IReadOnlyList<T> Lösung, wobei a (string[]) cast kann verwendet werden, um Schreibzugriff auf die Elemente zu erhalten , wie in mjepsen's hilfreiche Antwort .
      Die gleiche Schwachstelle gilt für die IReadOnlyCollection<T> Schnittstelle die trotz der Ähnlichkeit des Namens mit Klasse ReadOnlyCollection , unterstützt nicht einmal indiziert Zugang und ist damit grundsätzlich ungeeignet für einen Array-ähnlichen Zugriff).

1 Stimmen

@mortb: Leider, IReadOnlyCollection unterstützt keinen indizierten Zugriff und kann daher hier nicht verwendet werden. Außerdem, wie IReadOnlyList (die einen indizierten Zugriff hat), ist es anfällig für Elementmanipulationen durch Rückführung auf string[] . Mit anderen Worten: ReadOnlyCollection (in das man ein String-Array nicht casten kann) ist die robusteste Lösung. Nicht mit einem Getter ist eine Option (und ich habe die Antwort aktualisiert, um zu beachten, dass), aber mit öffentlich Daten ist es wahrscheinlich besser, bei einer Immobilie zu bleiben.

13voto

shurik Punkte 725

Der Vollständigkeit halber sei erwähnt, dass wir jetzt auch ImmutableArrays zur Verfügung haben. Diese sollten wirklich unveränderlich sein:

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

Erfordert System.Collections.Immutable NuGet-Referenz

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

11voto

Alastair Punkte 401

Sie können einen anderen Ansatz wählen: Definieren Sie eine konstante Zeichenkette, um Ihr Array zu repräsentieren, und teilen Sie die Zeichenkette dann in ein Array auf, wenn Sie sie benötigen, z. B.

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

Auf diese Weise erhalten Sie eine Konstante, die in der Konfiguration gespeichert und bei Bedarf in ein Array umgewandelt werden kann.

15 Stimmen

Meiner Meinung nach übersteigen die Kosten für die Durchführung der Aufteilung bei weitem die Vorteile, die sich aus der Festlegung von const ergeben. Aber +1 für einen einzigartigen Ansatz und das Denken außerhalb der Box;)

2 Stimmen

Ich war im Begriff, die gleiche Lösung zu posten und sah dann dies, im Gegensatz zu den harten und negativen Bemerkungen, dies war eigentlich perfekt für mein Szenario, wo ich brauchte, um eine Konst an ein Attribut zu übergeben, und dann habe ich den Wert in Attribut-Konstruktor aufgeteilt, um zu bekommen, was ich brauchte. und ich sehe keinen Grund, warum es Performance-Kosten haben wird, da Attribute nicht für jede Instanz erstellt werden.

11voto

Richard Garside Punkte 85284

Wenn Sie ein Array hinter einer IReadOnlyList-Schnittstelle deklarieren, erhalten Sie ein konstantes Array mit konstanten Werten, das zur Laufzeit deklariert wird:

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

Verfügbar in .NET 4.5 und höher.

5voto

skaz Punkte 21224

Ich glaube, man kann sie nur schreibgeschützt machen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X