Declarar un diccionario dentro de una clase estática

90

¿Cómo declarar un objeto de diccionario estático dentro de una clase estática? Lo intenté

public static class ErrorCode
{
    public const IDictionary<string, string> ErrorCodeDic = new Dictionary<string, string>()
    {
        { "1", "User name or password problem" }     
    };
}

Pero el compilador se queja de que " un campo constante de un tipo de referencia que no sea cadena solo se puede inicializar con nulo ".

Graviton
fuente
1
No puede usar const con el tipo Dictionary, solo con valores escalares. (verifique mi respuesta) msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx
Yona

Respuestas:

214

Si desea declarar el diccionario una vez y nunca cambiarlo, declare como de solo lectura:

private static readonly Dictionary<string, string> ErrorCodes
    = new Dictionary<string, string>
{
    { "1", "Error One" },
    { "2", "Error Two" }
};

Si desea que los elementos del diccionario sean de solo lectura (no solo la referencia, sino también los elementos de la colección), tendrá que crear una clase de diccionario de solo lectura que implemente IDictionary.

Consulte ReadOnlyCollection como referencia.

BTW const solo se puede usar al declarar valores escalares en línea.

Yona
fuente
¿Qué tal tener una variable estática privada de nivel de clase Diccionario estático privado <cadena, cadena> ErrorCodes y luego en la función respectiva verificar si (ErrorCodes == null) {llenar diccionario} para almacenar el valor cuando se usa en bucle?
LifeOfPi
1
Si no desea que se cambie el diccionario, puede ajustarlo en un archivo ReadOnlyDictionary. Una opción más eficiente (pero menos segura) es asignarlo a un IReadOnlyDictionarytipo.
Ramon de Klein
8

La sintaxis correcta (probada en VS 2008 SP1) es la siguiente:

public static class ErrorCode
{
    public static IDictionary<string, string> ErrorCodeDic;
     static ErrorCode()
    {
        ErrorCodeDic = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
    }
}
Graviton
fuente
Pero esto no impide que una clase consumidora modifique el contenido.
Everts
4

Antigua pregunta, pero me pareció útil. Resulta que también hay una clase especializada para un diccionario que usa una cadena tanto para la clave como para el valor:

private static readonly StringDictionary SegmentSyntaxErrorCodes = new StringDictionary
{
    { "1", "Unrecognized segment ID" },
    { "2", "Unexpected segment" }
};

Editar: según el comentario de Chris a continuación, generalmente se prefiere usar Dictionary<string, string>over, StringDictionarypero dependerá de su situación. Si está tratando con una base de código más antigua, es posible que esté limitado a StringDictionary. Además, tenga en cuenta que la siguiente línea:

myDict["foo"]

devolverá nulo si myDictes a StringDictionary, pero se lanzará una excepción en caso de Dictionary<string, string>. Consulte la publicación SO que mencionó para obtener más información, que es la fuente de esta edición.

areyling
fuente
Esa es exactamente la pregunta a la que me vinculé.
Chris Morgan
1
Ja, wow, ni siquiera lo entendí, simplemente encontré el mismo. No pude editar el comentario, así que edité la publicación para resumir en un solo lugar. ¡Gracias!
areyling
1

El problema con su ejemplo inicial se debió principalmente al uso de en constlugar de static; no puede crear una referencia constante no nula en C #.

Creo que esto también habría funcionado:

public static class ErrorCode
{
    public static IDictionary<string, string> ErrorCodeDic
        = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
}

Además, como señala Y Low, agregar también readonlyes una buena idea, y ninguno de los modificadores discutidos aquí evitará que el diccionario en sí sea modificado.

Charlie
fuente
1

Cree un constructor estático para agregar valores en el Diccionario

enum Commands
{
    StudentDetail
}
public static class Quires
{
    public static Dictionary<Commands, String> quire
        = new Dictionary<Commands, String>();
    static Quires()
    {
        quire.add(Commands.StudentDetail,@"SELECT * FROM student_b");
    }
}
Sujith Radhakrishnan
fuente
1
quire o consulta?
Ash
0

Convierta el diccionario en estático y nunca lo agregue fuera del ctor de su objeto estático. Esa parece ser una solución más simple que jugar con las reglas estáticas / const en C #.

Jeff Hubbard
fuente
-1

Puede usar el constructor estático / class para inicializar su diccionario:

public static class ErrorCode
{
    public const IDictionary<string, string> ErrorCodeDic;
    public static ErrorCode()
    {
        ErrorCodeDic = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
    }
}
Andy
fuente
1
¿Querías hacer que el diccionario fuera estático? No puedes tenerlo constante. Como dice el mensaje de error, solo los tipos de valor, cadenas o nulos pueden ser constantes
Orion Edwards
-2
public static class ErrorCode
{
    public const IDictionary<string , string > m_ErrorCodeDic;

    public static ErrorCode()
    {
      m_ErrorCodeDic = new Dictionary<string, string>()
             { {"1","User name or password problem"} };             
    }
}

Probablemente se inicialice en el constructor.

Craig
fuente