Inline tworzenie instancji stałej List


103

Próbuję zrobić coś takiego:

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

Ale niestety to nie działa:

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.

Jak mogę rozwiązać ten problem?



4
UWAGA: Zamknięcie tego pytania jako duplikatu było błędem. Powiązane pytanie dotyczy stałych tablic , to pytanie dotyczy stałych list . Chociaż oba podejścia zapewniają z grubsza tę samą funkcjonalność, są różne, a odpowiedzi są różne. Wspomniane są tylko odpowiedzi na to pytanie ReadOnlyCollection. Pytania są powiązane, ale żadne z nich nie jest duplikatem innego.
Athari,

Odpowiedzi:


192

constdotyczy stałych czasu kompilacji. Można to po prostu zrobić static readonly, ale dotyczyłoby to tylko METRICSsamej zmiennej (która zwykle powinna być Metryki, zgodnie z konwencjami nazewnictwa .NET ). Nie uczyniłoby to listy niezmienną - więc ktoś mógłby zadzwonićMETRICS.Add("shouldn't be here");

Możesz użyć a, ReadOnlyCollection<T>aby go owinąć. Na przykład:

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>po prostu otacza potencjalnie zmienną kolekcję, ale ponieważ nic innego nie będzie miało dostępu do List<T>późniejszej, możesz uznać całą kolekcję za niezmienną.

(Wielkie litery to głównie domysły - użycie pełniejszych nazw sprawiłoby, że byłyby jaśniejsze, IMO).

Czy zadeklarować ją jako IList<string>, IEnumerable<string>, ReadOnlyCollection<string>lub coś innego jest do ciebie ... jeśli można oczekiwać, że powinien być traktowany jedynie jako ciąg, a następnie IEnumerable<string>będzie prawdopodobnie najbardziej odpowiednie. Jeśli kolejność ma znaczenie i chcesz, aby ludzie mieli do niego dostęp za pomocą indeksu, IList<T>może być odpowiednie. Jeśli chcesz, aby niezmienność była widoczna, zadeklaruj ją jako ReadOnlyCollection<T>przydatną - ale nieelastyczną.


2
przyszedłem tutaj, szukając new List<string>{ ... }roli. Dzięki Jon :)
Jason

1
Przypuszczam, że jest powód, ale dla mnie to dziwne, że ReadOnlyCollectionwdraża się IList<>tak, jak to ujawnia.Add
AaronLS

25

Zamiast tego musisz użyć static readonlylisty. A jeśli chcesz, aby lista była niezmienna, możesz rozważyć użycie ReadOnlyCollection<T>zamiast 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

Szukasz prostego kodu, takiego jak ten:

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

Nie odpowiada to na pytanie, ponieważ tworzenie instancji właściwości jest potrzebą pytającego.
vchan
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.