Instansiasi sebaris dari Daftar konstanta

103

Saya mencoba melakukan sesuatu seperti ini:

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

Namun sayangnya ini tidak berhasil:

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.

Bagaimana saya bisa mengatasi masalah ini?

RoflcoptrException
sumber
4
CATATAN: Menutup pertanyaan ini sebagai duplikat adalah kesalahan. Pertanyaan terkait adalah tentang array konstan , pertanyaan ini tentang daftar konstan . Meskipun kedua pendekatan tersebut memberikan fungsi yang kira-kira sama, keduanya berbeda dan jawabannya berbeda. Hanya jawaban atas pertanyaan ini yang menyebutkan ReadOnlyCollection. Pertanyaan terkait, tetapi tidak ada yang duplikat dari yang lain.
Athari

Jawaban:

192

constadalah untuk konstanta waktu kompilasi. Anda bisa membuatnya static readonly, tetapi itu hanya akan berlaku untuk METRICSvariabel itu sendiri (yang biasanya harus Metrik, dengan konvensi penamaan .NET ). Itu tidak akan berhasil daftar itu tidak berubah - sehingga seseorang dapat meneleponMETRICS.Add("shouldn't be here");

Anda mungkin ingin menggunakan a ReadOnlyCollection<T>untuk membungkusnya. Sebagai contoh:

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> hanya membungkus koleksi yang berpotensi berubah, tetapi karena tidak ada orang lain yang akan memiliki akses ke List<T> setelahnya, Anda dapat menganggap keseluruhan koleksi sebagai tidak dapat diubah.

(Kapitalisasi di sini sebagian besar merupakan tebakan - menggunakan nama yang lebih lengkap akan membuatnya lebih jelas, IMO.)

Apakah Anda menyatakan sebagai IList<string>, IEnumerable<string>, ReadOnlyCollection<string>atau sesuatu yang lain terserah Anda ... jika Anda berharap bahwa hal itu harus diperlakukan sebagai urutan, maka IEnumerable<string>mungkin akan paling sesuai. Jika urutan penting dan Anda ingin orang dapat mengaksesnya dengan indeks, IList<T>mungkin sesuai. Jika Anda ingin membuat keabadian itu tampak, menyatakannya sebagai ReadOnlyCollection<T>bisa berguna - tetapi tidak fleksibel.

Jon Skeet
sumber
2
saya datang ke sini mencari new List<string>{ ... }bagian itu. Terima kasih Jon :)
Jason
1
Saya kira ada alasannya, tetapi bagi saya itu aneh bahwa ReadOnlyCollectionpenerapannya IList<>seperti yang diekspos.Add
AaronLS
25

Anda harus menggunakan static readonlydaftar sebagai gantinya. Dan jika Anda ingin daftar tersebut tidak dapat diubah, Anda mungkin ingin mempertimbangkan untuk menggunakan ReadOnlyCollection<T>daripada 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
sumber
-5

Anda mencari kode sederhana, seperti ini:

    List<string> tagList = new List<string>(new[]
    {
         "A"
        ,"B"
        ,"C"
        ,"D"
        ,"E"
    });
Agnaldo Junior
sumber
Ini tidak menjawab pertanyaan karena instansiasi properti adalah kebutuhan penanya.
vchan