Khởi tạo nội tuyến của một danh sách không đổi


101

Tôi cố gắng làm một cái gì đó như thế này:

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

Nhưng tiếc là điều này không hoạt động:

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.

Làm thế nào tôi có thể giải quyết vấn đề này?



4
LƯU Ý: Việc đóng câu hỏi này là một bản sao là một sai lầm. Câu hỏi liên kết là về mảng hằng , câu hỏi này là về danh sách hằng . Mặc dù cả hai cách tiếp cận đều cung cấp chức năng gần như giống nhau, chúng khác nhau và câu trả lời cũng khác nhau. Chỉ có câu trả lời cho câu hỏi này đề cập đến ReadOnlyCollection. Các câu hỏi có liên quan, nhưng không trùng lặp với một câu hỏi khác.
Athari

Câu trả lời:


191

constlà cho hằng số thời gian biên dịch. Bạn chỉ có thể làm cho nó static readonly, nhưng điều đó sẽ chỉ áp dụng cho METRICSchính biến (thay vào đó thường phải là Metrics, theo quy ước đặt tên .NET ). Nó sẽ không làm cho danh sách trở nên bất biến - vì vậy ai đó có thể gọiMETRICS.Add("shouldn't be here");

Bạn có thể muốn sử dụng một ReadOnlyCollection<T>để bọc nó. Ví dụ:

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>chỉ gói gọn một bộ sưu tập có khả năng thay đổi, nhưng vì không có gì khác sẽ có quyền truy cập List<T>sau đó, bạn có thể coi bộ sưu tập tổng thể là bất biến.

(Viết hoa ở đây chủ yếu là phỏng đoán - sử dụng tên đầy đủ hơn sẽ làm cho chúng rõ ràng hơn, IMO.)

Cho dù bạn khai báo nó như là IList<string>, IEnumerable<string>, ReadOnlyCollection<string>hay cái gì khác là tùy thuộc vào bạn ... nếu bạn hy vọng rằng nó chỉ nên được coi là một chuỗi, sau đó IEnumerable<string>có lẽ sẽ là thích hợp nhất. Nếu thứ tự quan trọng và bạn muốn mọi người có thể truy cập nó bằng chỉ mục, IList<T>có thể phù hợp. Nếu bạn muốn làm cho tính bất biến trở nên rõ ràng, việc khai báo nó ReadOnlyCollection<T>có thể hữu ích - nhưng không linh hoạt.


2
tôi đến đây để tìm new List<string>{ ... }một phần. Cảm ơn Jon :)
Jason

1
Tôi cho rằng có một lý do, nhưng với tôi đó là lẻ mà ReadOnlyCollectioncụ IList<>như phơi bày rằng.Add
AaronLS

25

static readonlyThay vào đó, bạn sẽ cần sử dụng một danh sách. Và nếu bạn muốn danh sách là bất biến thì bạn có thể muốn xem xét sử dụng ReadOnlyCollection<T>hơn là sử dụng 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

Bạn đang tìm kiếm một mã đơn giản, như sau:

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

Điều này không trả lời câu hỏi vì việc khởi tạo tài sản là nhu cầu của người hỏi.
vchan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.