Istanziazione inline di una costante List


103

Provo a fare qualcosa del genere:

public const List<String> METRICS = new List<String>()
        {
            SourceFile.LOC,
            SourceFile.MCCABE,
            SourceFile.NOM,
            SourceFile.NOA,
            SourceFile.FANOUT,
            SourceFile.FANIN,
            SourceFile.NOPAR,
            SourceFile.NDC,
            SourceFile.CALLS
        };

Ma sfortunatamente questo non funziona:

FileStorer.METRICS' is of type 'System.Collections.Generic.List<string>'. A const field of a reference type other than string can only be initialized with null.

Come posso risolvere questo problema?



4
NOTA: chiudere questa domanda come duplicato è stato un errore. La domanda collegata riguarda gli array costanti , questa domanda riguarda gli elenchi costanti . Sebbene entrambi gli approcci forniscano all'incirca la stessa funzionalità, sono diversi e le risposte sono diverse. Solo le risposte a questa menzione di domanda ReadOnlyCollection. Le domande sono correlate, ma nessuna delle due è duplicata di un'altra.
Athari

Risposte:


192

constè per le costanti in fase di compilazione. Si potrebbe solo rendere più static readonly, ma che si applicherebbe solo alla METRICSvariabile stessa (che dovrebbe essere tipicamente Metrics invece, da .NET convenzioni di denominazione ). Non renderebbe la lista immutabile, quindi qualcuno potrebbe chiamareMETRICS.Add("shouldn't be here");

Puoi usare un ReadOnlyCollection<T>per avvolgerlo. Per esempio:

public static readonly IList<String> Metrics = new ReadOnlyCollection<string>
    (new List<String> { 
         SourceFile.LoC, SourceFile.McCabe, SourceFile.NoM,
         SourceFile.NoA, SourceFile.FanOut, SourceFile.FanIn, 
         SourceFile.Par, SourceFile.Ndc, SourceFile.Calls });

ReadOnlyCollection<T>avvolge solo una raccolta potenzialmente mutabile, ma poiché nient'altro avrà accesso a quella List<T>successiva, puoi considerare la raccolta complessiva come immutabile.

(Le maiuscole qui sono per lo più congetture: l'uso di nomi più completi li renderebbe più chiari, IMO.)

Sia che si dichiara come IList<string>, IEnumerable<string>, ReadOnlyCollection<string>o qualcos'altro sta a voi ... se vi aspettate che dovrebbe essere trattato solo come una sequenza, allora IEnumerable<string>sarebbe probabilmente più opportuno. Se l'ordine è importante e desideri che le persone possano accedervi tramite indice, IList<T>potrebbe essere appropriato. Se vuoi rendere evidente l'immutabilità, dichiararla come ReadOnlyCollection<T>potrebbe essere utile, ma inflessibile.


2
Sono venuto qui cercando la new List<string>{ ... }parte. Grazie Jon :)
Jason

1
Suppongo che ci sia una ragione, ma per me è strano che ReadOnlyCollectionimplementi IList<>come si rivela.Add
AaronLS

25

Dovrai static readonlyinvece utilizzare un elenco. E se vuoi che l'elenco sia immutabile, potresti prendere in considerazione l'utilizzo ReadOnlyCollection<T>anziché List<T>.

private static readonly ReadOnlyCollection<string> _metrics =
    new ReadOnlyCollection<string>(new[]
        {
            SourceFile.LOC,
            SourceFile.MCCABE,
            SourceFile.NOM,
            SourceFile.NOA,
            SourceFile.FANOUT,
            SourceFile.FANIN,
            SourceFile.NOPAR,
            SourceFile.NDC,
            SourceFile.CALLS
        });

public static ReadOnlyCollection<string> Metrics
{
    get { return _metrics; }
}

-5

Stai cercando un codice semplice, come questo:

    List<string> tagList = new List<string>(new[]
    {
         "A"
        ,"B"
        ,"C"
        ,"D"
        ,"E"
    });

Questo non risponde alla domanda poiché l'istanza di una proprietà è la necessità dell'interrogante.
vchan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.