Dichiarare un dizionario all'interno di una classe statica


90

Come dichiarare un oggetto dizionario statico all'interno di una classe statica? Provai

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

Ma il compilatore lamenta che " Un campo const di un tipo di riferimento diverso da stringa può essere inizializzato solo con null ".


1
Non è possibile utilizzare const con il tipo Dictionary, solo con valori scalari. (controlla la mia risposta) msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx
Yona

Risposte:


214

Se vuoi dichiarare il dizionario una volta e non cambiarlo mai, dichiaralo come di sola lettura:

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

Se si desidera che gli elementi del dizionario siano di sola lettura (non solo il riferimento ma anche gli elementi nella raccolta), sarà necessario creare una classe di dizionario di sola lettura che implementa IDictionary.

Dai un'occhiata a ReadOnlyCollection per riferimento.

La const BTW può essere utilizzata solo quando si dichiarano valori scalari inline.


Che ne dici di avere una variabile statica privata a livello di classe private static Dictionary <string, string> ErrorCodes e quindi nella rispettiva funzione controlla se (ErrorCodes == null) {fill dictionary} per memorizzare nella cache il valore quando viene utilizzato in loop?
LifeOfPi

1
Se non desideri modificare il dizionario, puoi racchiuderlo in un file ReadOnlyDictionary. Un'opzione più efficiente (ma meno sicura) è assegnarlo a un IReadOnlyDictionarytipo.
Ramon de Klein

8

La sintassi corretta (come testata in VS 2008 SP1) è questa:

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

Ma ciò non impedisce a una classe consumatrice di modificare il contenuto.
Everts

4

Vecchia domanda, ma l'ho trovata utile. Si scopre che esiste anche una classe specializzata per un dizionario che utilizza una stringa sia per la chiave che per il valore:

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

Modifica: secondo il commento di Chris di seguito, l'uso di Dictionary<string, string>over StringDictionaryè generalmente preferito ma dipenderà dalla tua situazione. Se hai a che fare con una vecchia base di codice, potresti essere limitato a StringDictionary. Inoltre, nota che la seguente riga:

myDict["foo"]

restituirà null se myDictè a StringDictionary, ma verrà generata un'eccezione in caso di Dictionary<string, string>. Vedere il post SO che ha menzionato per ulteriori informazioni, che è la fonte di questa modifica.



Questa è esattamente la domanda a cui mi sono collegato.
Chris Morgan

1
Ha wow, non l'ho nemmeno capito - è solo successo di trovare lo stesso. Non ho potuto modificare il commento, quindi ho modificato il post per riassumere in un unico posto. Grazie!
areyling

1

Il problema con il tuo esempio iniziale era principalmente dovuto all'uso di constpiuttosto chestatic ; non è possibile creare un riferimento const non null in C #.

Credo che anche questo avrebbe funzionato:

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

Inoltre, come sottolinea Y Low, anche l'aggiunta readonlyè una buona idea, e nessuno dei modificatori discussi qui impedirà la modifica del dizionario stesso.


1

Crea un costruttore statico per aggiungere valori nel dizionario

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

1
cudiero o domanda?
Ash

0

Rendi il dizionario statico e non aggiungerlo mai al di fuori del ctor dell'oggetto statico. Sembra essere una soluzione più semplice rispetto alle regole statiche / const in C #.



-1

Puoi usare il costruttore statico / class per inizializzare il tuo dizionario:

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

1
Volevi rendere statico il dizionario? Non puoi averlo const. Come dice il messaggio di errore, solo i tipi di valore, stringhe o null possono essere const
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"} };             
    }
}

Probabilmente inizializzare nel costruttore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.