Instanciation en ligne d'une liste constante


103

J'essaye de faire quelque chose comme ça:

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

Mais malheureusement, cela ne fonctionne pas:

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.

Comment puis-je résoudre ce problème?



4
REMARQUE: Clôturer cette question comme un double était une erreur. La question liée concerne les tableaux de constantes , cette question concerne les listes de constantes . Bien que les deux approches fournissent à peu près la même fonctionnalité, elles sont différentes et les réponses sont différentes. Seules les réponses à cette question mentionnent ReadOnlyCollection. Les questions sont liées, mais aucune n'est en double.
Athari

Réponses:


192

constest pour les constantes de compilation. Vous pouvez simplement le faire static readonly, mais cela ne s'appliquerait qu'à la METRICSvariable elle-même (qui devrait généralement être des métriques à la place, selon les conventions de dénomination .NET ). Cela ne rendrait pas la liste immuable - pour que quelqu'un puisse appelerMETRICS.Add("shouldn't be here");

Vous voudrez peut-être utiliser un ReadOnlyCollection<T>pour l'envelopper. Par exemple:

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>encapsule juste une collection potentiellement mutable, mais comme rien d'autre n'aura accès à la List<T>suite, vous pouvez considérer la collection globale comme immuable.

(La capitalisation ici est principalement une supposition - l'utilisation de noms plus complets les rendrait plus clairs, IMO.)

Que vous déclarez comme IList<string>, IEnumerable<string>, ReadOnlyCollection<string>ou quelque chose d' autre à vous ... si vous attendez qu'il ne doit être traitée comme une séquence, puis IEnumerable<string>serait probablement plus approprié. Si l'ordre est important et que vous souhaitez que les utilisateurs puissent y accéder par index, cela IList<T>peut être approprié. Si vous voulez rendre l'immuabilité apparente, déclarez-la comme ReadOnlyCollection<T>étant pratique - mais inflexible.


2
Je suis venu ici à la recherche de la new List<string>{ ... }pièce. Merci Jon :)
Jason

1
Je suppose qu'il y a une raison, mais pour moi, c'est étrange que cela ReadOnlyCollectionimplémente IList<>comme cela expose.Add
AaronLS

25

Vous devrez utiliser un static readonly liste à la place. Et si vous souhaitez que la liste soit immuable, vous pouvez envisager d'utiliser ReadOnlyCollection<T>plutôt que 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

Vous recherchez un code simple, comme celui-ci:

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

Cela ne répond pas à la question puisque l'instanciation d'une propriété est le besoin du questionneur.
vchan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.