Вбудована інстанція постійного Списку


102

Я намагаюся зробити щось подібне:

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

Але, на жаль, це не працює:

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.

Як я можу вирішити цю проблему?



4
ПРИМІТКА. Помилка закриття цього питання як дубліката. Зв'язане питання стосується постійних масивів , це питання про постійні списки . Хоча обидва підходи забезпечують приблизно однаковий функціонал, вони різні, а відповіді - різні. Згадайте лише відповіді на це запитання ReadOnlyCollection. Питання пов'язані між собою, але жоден з них не дублює іншого.
Афарі

Відповіді:


192

constпризначений для констант часу компіляції. Ви можете просто зробити це static readonly, але це стосується лише самої METRICSзмінної (яка, як правило, має бути "Метрики", умовами .NET іменування ). Це не зробить список незмінним - щоб хтось міг зателефонуватиMETRICS.Add("shouldn't be here");

Можливо, ви хочете використовувати його, ReadOnlyCollection<T>щоб обернути його. Наприклад:

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>просто обгортає потенційно змінену колекцію, але оскільки більше нічого після цього не матиме доступу List<T>, ви можете вважати загальну колекцію непорушною.

(Велика література тут переважно здогадка - використання більш повних імен зробить їх зрозумілішими, IMO.)

Якщо ви оголошуєте його як IList<string>, IEnumerable<string>, ReadOnlyCollection<string>або що - то ще до вас ... якщо ви очікуєте , що вона повинна розглядатися тільки як послідовність, то IEnumerable<string>, ймовірно , буде найбільш підходящим. Якщо замовлення має значення, і ви хочете, щоб люди мали доступ до нього за індексом, IList<T>можливо, це буде доречно. Якщо ви хочете зробити незмінність очевидною, оголосивши її як ReadOnlyCollection<T>можна зручно - але негнучко.


2
Я прийшов сюди шукати new List<string>{ ... }частину. Дякую Йону :)
Джейсон

1
Я припускаю, що є причина, але для мене це дивно, що ReadOnlyCollectionреалізується IList<>так, як це викриває.Add
AaronLS

25

Вам static readonlyзамість цього доведеться використовувати список. І якщо ви хочете, щоб список був непорушним, тоді ви можете розглянути можливість використання, ReadOnlyCollection<T>а не 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

Ви шукаєте простий код, наприклад:

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

Це не дає відповіді на питання, оскільки інстанціювання майна є потребою запитувача.
вчан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.