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"};

923voto

Cody Gray Punkte 229889

Ja, aber Sie müssen es anmelden readonly 代わりに const :

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

Der Grund dafür ist, dass const kann nur auf ein Feld angewendet werden, dessen Wert zur Kompilierzeit bekannt ist. Der Array-Initialisierer, den Sie gezeigt haben, ist kein konstanter Ausdruck in C#, so dass er einen Compilerfehler erzeugt.

Die Erklärung readonly löst dieses Problem, da der Wert erst zur Laufzeit initialisiert wird (obwohl er garantiert schon vor der ersten Verwendung des Arrays initialisiert wurde).

Je nachdem, was Sie letztendlich erreichen wollen, können Sie auch die Deklaration einer Aufzählung in Betracht ziehen:

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

150 Stimmen

Beachten Sie, dass die Array hier ist natürlich nicht schreibgeschützt; Titles[2]="Welsh"; würde zur Laufzeit gut funktionieren

53 Stimmen

Sie wollen es wahrscheinlich auch statisch

4 Stimmen

Wie wäre es, ein "const"-Array in einem Methodenkörper zu deklarieren, nicht in dem der Klasse?

88voto

JAiro Punkte 5652

Sie können kein 'const' Array erstellen, da Arrays Objekte sind und nur zur Laufzeit erstellt werden können und const-Entitäten zur Kompilierzeit aufgelöst werden.

Stattdessen können Sie Ihr Array als "readonly" deklarieren. Dies hat den gleiche Wirkung wie const, außer dass der Wert zur Laufzeit gesetzt werden kann. Er kann nur einmal gesetzt werden und ist danach ein readonly (d.h. konstanter) Wert.

9 Stimmen

Dieser Beitrag zeigt, warum Arrays nicht als Konstanten deklariert werden können

9 Stimmen

Es ist möglich, ein konstantes Array zu deklarieren; das Problem ist, es mit einem konstanten Wert zu initialisieren. Das einzige funktionierende Beispiel, das mir einfällt, ist const int[] a = null; was nicht sehr nützlich ist, aber tatsächlich eine Instanz einer Array-Konstante.

71voto

Branimir Punkte 4221

Sie können Array deklarieren als readonly , aber denken Sie daran, dass Sie das Element der readonly Array.

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

Erwägen Sie die Verwendung von enum, wie von Cody vorgeschlagen, oder IList.

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

39 Stimmen

In .NET 4.5 und höher können Sie eine Liste als IReadOnlyList<string> anstelle von IList<string> deklarieren.

5 Stimmen

Nur zur Klarstellung: Sie können die Werte in einer IReadOnlyList immer noch ändern (nur keine Elemente hinzufügen oder entfernen). Aber ja, deklarieren es als eine IReadOnlyList wäre besser als eine IList.

67voto

Roger Hill Punkte 2963

Dies ist die einzig richtige Antwort. Sie können dies derzeit nicht tun.

Alle anderen Antworten schlagen die Verwendung statischer Nur-Lese-Variablen vor, die ähnlich wie aber nicht dasselbe wie eine Konstante. Eine Konstante ist fest in der Baugruppe kodiert. Eine statische schreibgeschützte Variable kann nur einmal festgelegt werden, wahrscheinlich bei der Initialisierung eines Objekts.

Diese sind manchmal austauschbar, aber nicht immer.

EDITAR : Ich dachte, ich werfe dies ein, da es scheint, wie die Person, die die Frage gestellt wurde ein wenig verschwommen über Arrays. Wenn Sie ein Array deklarieren, ist es ein Zeiger auf ein Speichersegment, das das Array enthält. Es ist sehr einfach, da es nur eine Adresse ist, ohne komplexe Logik, die steuert, ob es lesbar oder schreibbar ist. Sie erhalten einen Zeiger, mit dem Sie tun können, was Sie wollen.

Dies ist einer der Gründe, warum es ein wenig schwierig ist, ein unveränderliches Array zu erstellen. Man könnte eine Klasse schreiben, die das Array umhüllt und nur das Lesen zulässt, indem man eine Kopie zurückgibt, aber dann ist es nicht mehr wirklich ein Array, sondern ein Objekt, das ein Array umhüllt.

Einige Leute haben vorgeschlagen, static oder readonly zu verwenden, um das Verhalten zu simulieren, das Sie sehen würden, wenn Sie const array erstellen könnten. Diese haben einige Nebeneffekte, die für den Gelegenheitsleser nicht offensichtlich sein könnten.

Um wirklich ein const-Array zu erhalten, müsste C# und der MSIL zugrunde liegende Code aktualisiert werden, um das Lesen aus einem Array, aber nicht das Schreiben zu ermöglichen.

1 Stimmen

Ich danke Ihnen. Ich habe mich gefragt, warum die am häufigsten hochgestuften Lösungen für Standardparameter nicht funktionieren.

27voto

mjepson Punkte 795

Seit C# 6 können Sie es so schreiben:

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

Siehe auch: C#: Das neue und verbesserte C# 6.0 (insbesondere das Kapitel "Ausdruckskörperliche Funktionen und Eigenschaften")

Dadurch wird eine statische Eigenschaft schreibgeschützt, aber Sie können den Inhalt des zurückgegebenen Arrays immer noch ändern, aber wenn Sie die Eigenschaft erneut aufrufen, erhalten Sie wieder das ursprüngliche, unveränderte Array.

Zur Klarstellung: Dieser Code ist dasselbe wie (oder eigentlich eine Abkürzung für):

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

Bitte beachten Sie, dass dieser Ansatz eine Kehrseite hat: Für jeden Verweis wird ein neues Array instanziiert. Wenn Sie also ein sehr großes Array verwenden, ist dies möglicherweise nicht die effizienteste Lösung. Wenn Sie jedoch dasselbe Array wiederverwenden (z. B. in einem privaten Attribut), eröffnet dies wiederum die Möglichkeit, den Inhalt des Arrays zu ändern.

Wenn Sie ein unveränderliches Array (oder eine Liste) haben möchten, können Sie auch verwenden:

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

Dies birgt jedoch immer noch ein Risiko für Änderungen, da man sie immer noch in einen string[] zurückverwandeln und den Inhalt ändern kann:

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

4 Stimmen

Welchen Vorteil hat die Verwendung von Eigenschaft anstelle von Feld in diesem Fall?

5 Stimmen

Ein Feld kann nicht bei jedem Aufruf ein neues Objekt zurückgeben. Eine Eigenschaft ist im Grunde eine Art "verdeckte Funktion".

1 Stimmen

Wenn Sie sich auf die letzte Option beziehen, kann dies sowohl mit einem Feld als auch mit einer Eigenschaft geschehen, aber da es öffentlich ist, bevorzuge ich eine Eigenschaft. Seit der Einführung von Eigenschaften verwende ich nie ein öffentliches Feld.

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