Creación de instancias en línea de una lista constante

101

Intento hacer algo como esto:

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

Pero desafortunadamente esto no 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 puedó resolver esté problema?

RoflcoptrException
fuente
4
NOTA: Cerrar esta pregunta como duplicado fue un error. La pregunta vinculada es sobre matrices constantes , esta pregunta trata sobre listas constantes . Aunque ambos enfoques proporcionan aproximadamente la misma funcionalidad, son diferentes y las respuestas son diferentes. Solo se mencionan las respuestas a esta pregunta ReadOnlyCollection. Las preguntas están relacionadas, pero ninguna es un duplicado de otra.
Athari

Respuestas:

191

constes para constantes en tiempo de compilación. Usted podría simplemente hacer que sea static readonly, pero que sólo se aplicaría a la METRICSpropia variable (que por lo general debe ser Métrica lugar, por .NET convenciones de nombres ). No haría que la lista fuera inmutable, por lo que alguien podría llamarMETRICS.Add("shouldn't be here");

Es posible que desee utilizar un ReadOnlyCollection<T>para envolverlo. Por ejemplo:

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>simplemente envuelve una colección potencialmente mutable, pero como nada más tendrá acceso a la List<T>posterior, puede considerar la colección general como inmutable.

(Las mayúsculas aquí son principalmente conjeturas: usar nombres más completos los aclararía, en mi opinión).

Si se declara como IList<string>, IEnumerable<string>, ReadOnlyCollection<string>o alguna otra cosa depende de usted ... si esperas que sólo debe ser tratada como una secuencia, entonces IEnumerable<string>probablemente sería más apropiado. Si el orden es importante y desea que las personas puedan acceder a él por índice, IList<T>puede ser apropiado. Si desea que la inmutabilidad sea aparente, declare que ReadOnlyCollection<T>podría ser útil, pero inflexible.

Jon Skeet
fuente
2
Vine aquí buscando el new List<string>{ ... }papel. Gracias Jon :)
Jason
1
Supongo que hay una razón, pero para mí es extraño que ReadOnlyCollectionimplemente IList<>lo que expone.Add
AaronLS
25

En su lugar, deberá utilizar una static readonlylista. Y si desea que la lista sea inmutable, entonces debería considerar usar en ReadOnlyCollection<T>lugar 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; }
}
LukeH
fuente
-5

Estás buscando un código simple, como este:

    List<string> tagList = new List<string>(new[]
    {
         "A"
        ,"B"
        ,"C"
        ,"D"
        ,"E"
    });
Agnaldo Junior
fuente
Esto no responde a la pregunta ya que la instanciación de una propiedad es una necesidad del interrogador.
vchan