variable - c# insert int into array




Dichiara un array const (9)

È possibile scrivere qualcosa di simile al seguente?

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

È possibile dichiarare array come readonly , ma tenere presente che è possibile modificare l'elemento dell'array readonly .

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

Considera l'uso di enum, come suggerito da Cody, o IList.

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

Credo che puoi renderlo solo in sola lettura.


Gli array sono probabilmente una di quelle cose che possono essere valutate solo in fase di runtime. Le costanti devono essere valutate al momento della compilazione. Prova a utilizzare "readonly" anziché "const".


In alternativa, per aggirare il problema degli elementi che possono essere modificati con un array di sola lettura, è possibile utilizzare invece una proprietà statica. (I singoli elementi possono ancora essere modificati, ma queste modifiche verranno apportate solo sulla copia locale dell'array.)

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

Ovviamente, questo non sarà particolarmente efficiente in quanto ogni volta viene creato un nuovo array di stringhe.


Per completezza, ora abbiamo a nostra disposizione anche gli ImmutableArray. Questo dovrebbe essere veramente immutabile:

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

Richiede System.Collections.Immutable riferimento NuGet

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


Per i miei bisogni, definisco array static , invece di impossibile const e funziona: public static string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };


Sì, ma devi dichiararlo di readonly anziché const :

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

Il motivo è che const può essere applicato solo a un campo il cui valore è noto in fase di compilazione. L'inizializzatore dell'array che hai mostrato non è un'espressione costante in C #, quindi produce un errore del compilatore.

La dichiarazione in readonly risolve il problema in quanto il valore non è inizializzato fino al momento dell'esecuzione (sebbene sia garantito l'inizializzazione prima della prima volta in cui viene utilizzato l'array).

A seconda di ciò che alla fine vuoi raggiungere, potresti anche considerare di dichiarare un enum:

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

Se dichiari una matrice dietro un'interfaccia IReadOnlyList ottieni una matrice costante con valori costanti che viene dichiarata in fase di runtime:

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

Disponibile in .NET 4.5 e versioni successive.


Una soluzione .NET Framework v4.5 + che migliora la risposta di tdbeckett :

using System.Collections.ObjectModel;

// ...

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

Nota: Dato che la raccolta è concettualmente costante, può essere sensato renderla static per dichiararla a livello di classe .

Quanto sopra:

  • Inizializza il campo di supporto implicito della proprietà una volta con l'array.

    • Nota che { get; } { get; } - cioè, dichiarando solo un getter di proprietà - è ciò che rende la proprietà stessa implicitamente di sola lettura (provare a combinare readonly con { get; } è in realtà un errore di sintassi).

    • In alternativa, puoi semplicemente omettere { get; } { get; } e aggiungere readonly per creare un campo invece di una proprietà, come nella domanda, ma esporre i membri dei dati pubblici come proprietà piuttosto che come campi è una buona abitudine da formare.

  • Crea una struttura a forma di array (che consente l'accesso indicizzato) che è veramente e di sola lettura (concettualmente, costante, una volta creata), entrambi rispetto a:

    • impedire la modifica della raccolta (ad esempio rimuovendo o aggiungendo elementi o sostituendo la raccolta nel suo complesso)
    • impedendo la modifica di singoli elementi.
      (Anche la modifica indiretta non è possibile, diversamente dalla soluzione IReadOnlyList<T> , dove è possibile utilizzare una cast (string[]) per ottenere l'accesso in scrittura agli elementi, come mostrato nella risposta utile di mjepsen .
      La stessa vulnerabilità si applica all'interfaccia IReadOnlyCollection<T> , che, nonostante il suo nome somiglianza alla classe ReadOnlyCollection , non supporta nemmeno l'accesso indicizzato , rendendolo fondamentalmente inadatto per fornire un accesso di tipo array).




readonly