Declarar una matriz constante

Resuelto Jaime Oro asked hace 13 años • 16 respuestas

¿Es posible escribir algo similar a lo siguiente?

public const string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
Jaime Oro avatar Feb 28 '11 20:02 Jaime Oro
Aceptado

Sí, pero debes declararlo readonlyen lugar de const:

public static readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };

La razón es que constsolo se puede aplicar a un campo cuyo valor se conoce en tiempo de compilación. El inicializador de matriz que ha mostrado no es una expresión constante en C#, por lo que produce un error de compilación.

Declararlo readonlyresuelve ese problema porque el valor no se inicializa hasta el tiempo de ejecución (aunque se garantiza que se inicializará antes de la primera vez que se use la matriz).

Dependiendo de lo que quieras lograr en última instancia, también podrías considerar declarar una enumeración:

public enum Titles { German, Spanish, Corrects, Wrongs };
Cody Gray - on strike avatar Feb 28 '2011 13:02 Cody Gray - on strike

No puede crear una matriz 'constante' porque las matrices son objetos y solo se pueden crear en tiempo de ejecución y las entidades constantes se resuelven en tiempo de compilación.

Lo que puedes hacer en su lugar es declarar tu matriz como "sólo lectura". Esto tiene el mismo efecto que const excepto que el valor se puede establecer en tiempo de ejecución. Sólo se puede establecer una vez y, a partir de entonces, es un valor de sólo lectura (es decir, constante).

JAiro avatar Feb 28 '2011 13:02 JAiro

Ésta es la única respuesta correcta. Actualmente no puedes hacer esto.

Todas las demás respuestas sugieren el uso de variables estáticas de solo lectura que son similares, pero no iguales, a una constante. Una constante está codificada de forma rígida en el ensamblaje. Una variable estática de solo lectura se puede configurar una vez, probablemente cuando se inicializa un objeto.

A veces son intercambiables, pero no siempre.

EDITAR : Pensé en incluir esto, ya que parece que la persona que hizo la pregunta estaba un poco confusa acerca de las matrices. Cuando declara una matriz, es un puntero a un segmento de memoria que contiene la matriz. Es muy simple porque es solo una dirección, sin una lógica compleja que controle si es legible o escribible. Te da un puntero y puedes hacer lo que quieras con él.

Esta es parte de la razón por la cual es un poco complicado crear una matriz inmutable. Podría escribir una clase que envuelva la matriz y solo permita su lectura devolviendo una copia, pero ya no es solo una matriz, es un objeto que envuelve una matriz.

Algunas personas han sugerido usar estática o de solo lectura para simular el comportamiento que vería si pudiera crear una matriz constante. Estos tienen algunos efectos secundarios que pueden no ser obvios para el lector casual. Además, si marca una matriz como de solo lectura, está marcando el puntero a la matriz, no la matriz en sí. Puedes cambiar el contenido de la matriz tanto como quieras:

public class Demo
{
    private readonly int[] _foo = new int[] {0,1,2,3};
    
    public void ChangeArray()
    {
        _foo[1] = 42; // works
        _foo = new int[] { 0, 1, 2, 3, 5 }; // won't even compile
    }
}

Para obtener realmente una matriz constante, sería necesario actualizar C# y el código subyacente MSIL para permitir la lectura de una matriz, pero no la escritura. Las otras propuestas en esta página son varias formas creativas de solucionar este problema.

Roger Hill avatar Apr 05 '2020 21:04 Roger Hill

Puede declarar la matriz como readonly, pero tenga en cuenta que puede cambiar el elemento de readonlyla matriz.

public readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
...
Titles[0] = "bla";

Considere usar enum, como sugirió Cody, o IList.

public readonly IList<string> ITitles = new List<string> {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
Branimir avatar Feb 28 '2011 13:02 Branimir