Inline-Instanziierung einer konstanten Liste

101

Ich versuche so etwas zu tun:

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

Aber leider funktioniert das nicht:

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.

Wie kann ich dieses Problem lösen?

RoflcoptrException
quelle
4
HINWEIS: Das Schließen dieser Frage als Duplikat war ein Fehler. Die verknüpfte Frage bezieht sich auf konstante Arrays , diese Frage bezieht sich auf konstante Listen . Obwohl beide Ansätze ungefähr die gleiche Funktionalität bieten, sind sie unterschiedlich und die Antworten sind unterschiedlich. Nur Antworten auf diese Frage erwähnen ReadOnlyCollection. Fragen sind verwandt, aber keines ist ein Duplikat eines anderen.
Athari

Antworten:

191

constist für Konstanten zur Kompilierungszeit. Sie könnten es einfach machen static readonly, aber das würde nur für die METRICSVariable selbst gelten (die normalerweise gemäß .NET-Namenskonventionen Metriken sein sollte ). Es würde die Liste nicht unveränderlich machen - also könnte jemand anrufenMETRICS.Add("shouldn't be here");

Möglicherweise möchten Sie ein verwenden ReadOnlyCollection<T>, um es zu verpacken. Beispielsweise:

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>Wraps nur eine potenziell veränderbare Sammlung, aber da nichts anderes Zugriff auf die nachfolgende Sammlung hat, List<T>können Sie die gesamte Sammlung als unveränderlich betrachten.

(Die Großschreibung hier ist meistens eine Vermutung - die Verwendung vollständigerer Namen würde sie klarer machen, IMO.)

Ob als erklären IList<string>, IEnumerable<string>, ReadOnlyCollection<string>oder etwas anderes ist an Ihnen ... wenn Sie erwarten , dass es sollte nur als eine Folge behandelt werden, dann IEnumerable<string>wäre wahrscheinlich am besten geeignet sein. Wenn die Reihenfolge wichtig ist und Sie möchten, dass Personen über den Index darauf zugreifen können, ist dies IList<T>möglicherweise angemessen. Wenn Sie die Unveränderlichkeit sichtbar machen möchten, erklären Sie sie als ReadOnlyCollection<T>praktisch - aber unflexibel.

Jon Skeet
quelle
2
Ich kam hierher auf der Suche nach dem new List<string>{ ... }Teil. Danke Jon :)
Jason
1
Ich nehme an, es gibt einen Grund, aber für mich ist es seltsam , dass ReadOnlyCollectionGeräte IList<>wie das entlarvt.Add
AaronLS
25

Sie müssen static readonlystattdessen eine Liste verwenden. Und wenn Sie möchten, dass die Liste unveränderlich ist, sollten Sie sie ReadOnlyCollection<T>lieber verwenden als 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; }
}
LukeH
quelle
-5

Sie suchen nach einem einfachen Code wie diesem:

    List<string> tagList = new List<string>(new[]
    {
         "A"
        ,"B"
        ,"C"
        ,"D"
        ,"E"
    });
Agnaldo Junior
quelle
Dies beantwortet die Frage nicht, da die Instanziierung einer Eigenschaft das Bedürfnis des Fragestellers ist.
Vchan