Instanciação inline de uma lista constante


101

Tento fazer algo assim:

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

Mas, infelizmente, isso não funciona:

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.

Como posso resolver esse problema?



4
NOTA: Fechar esta pergunta como uma duplicata foi um erro. A questão vinculada é sobre matrizes constantes , esta questão é sobre listas constantes . Embora ambas as abordagens forneçam aproximadamente a mesma funcionalidade, elas são diferentes e as respostas são diferentes. Apenas as respostas a esta pergunta mencionam ReadOnlyCollection. As perguntas estão relacionadas, mas nenhuma é duplicada da outra.
Athari

Respostas:


191

consté para constantes de tempo de compilação. Você poderia simplesmente fazer isso static readonly, mas isso só se aplicaria à METRICSprópria variável (que normalmente deveria ser Metrics, pelas convenções de nomenclatura .NET ). Isso não tornaria a lista imutável - para que alguém pudesse ligarMETRICS.Add("shouldn't be here");

Você pode querer usar um ReadOnlyCollection<T>para embrulhá-lo. Por exemplo:

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>apenas envolve uma coleção potencialmente mutável, mas como nada mais terá acesso a ela List<T>, você pode considerar a coleção geral como imutável.

(A capitalização aqui é principalmente uma suposição - usar nomes mais completos os tornaria mais claros, IMO.)

Se você declará-lo como IList<string>, IEnumerable<string>, ReadOnlyCollection<string>ou qualquer outra coisa é com você ... se você espera que ele só deve ser tratado como uma seqüência, em seguida, IEnumerable<string>provavelmente seria mais adequado. Se o pedido for importante e você quiser que as pessoas possam acessá-lo por índice, IList<T>pode ser apropriado. Se você quiser tornar a imutabilidade aparente, declarar que ReadOnlyCollection<T>pode ser útil - mas inflexível.


2
vim aqui procurando o new List<string>{ ... }papel. Obrigado Jon :)
Jason

1
Suponho que haja uma razão, mas para mim é estranho que ReadOnlyCollectionimplemente IList<>como expõe.Add
AaronLS

25

Você precisará usar uma static readonlylista. E se você deseja que a lista seja imutável, convém usar em ReadOnlyCollection<T>vez de 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

Você está procurando um código simples, como este:

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

Isso não responde à pergunta, pois a instanciação de uma propriedade é uma necessidade do questionador.
vchan
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.