Déclarer un dictionnaire dans une classe statique

90

Comment déclarer un objet dictionnaire statique dans une classe statique? j'ai essayé

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

Mais le compilateur se plaint que " Un champ const d'un type de référence autre que string ne peut être initialisé qu'avec null ".

Graviton
la source
1
Vous ne pouvez pas utiliser const avec le type Dictionary, uniquement avec des valeurs scalaires. (vérifiez ma réponse) msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx
Yona

Réponses:

214

Si vous souhaitez déclarer le dictionnaire une fois et ne jamais le modifier, déclarez-le en lecture seule:

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

Si vous souhaitez que les éléments du dictionnaire soient en lecture seule (pas seulement la référence, mais également les éléments de la collection), vous devrez créer une classe de dictionnaire en lecture seule qui implémente IDictionary.

Consultez ReadOnlyCollection pour référence.

BTW const ne peut être utilisé que lors de la déclaration de valeurs scalaires en ligne.

Yona
la source
Que diriez-vous d'avoir une variable statique privée au niveau de la classe Dictionnaire statique privé <string, string> ErrorCodes, puis dans la fonction respective, vérifiez si (ErrorCodes == null) {fill dictionary} pour mettre en cache la valeur lorsqu'elle est utilisée en boucle?
LifeOfPi
1
Si vous ne souhaitez pas que le dictionnaire soit modifié, vous pouvez l'envelopper dans un fichier ReadOnlyDictionary. Une option plus efficace (mais moins sûre) consiste à l'attribuer à un IReadOnlyDictionarytype.
Ramon de Klein
8

La syntaxe correcte (telle que testée dans VS 2008 SP1) est la suivante:

public static class ErrorCode
{
    public static IDictionary<string, string> ErrorCodeDic;
     static ErrorCode()
    {
        ErrorCodeDic = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
    }
}
Graviton
la source
Mais cela n'empêche pas une classe consommatrice de modifier le contenu.
Everts
4

Ancienne question, mais j'ai trouvé cela utile. Il s'avère qu'il existe également une classe spécialisée pour un dictionnaire utilisant une chaîne à la fois pour la clé et la valeur:

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

Edit: Selon le commentaire de Chris ci-dessous, l'utilisation de Dictionary<string, string>over StringDictionaryest généralement préférée mais dépendra de votre situation. Si vous avez affaire à une base de code plus ancienne, vous pourriez être limité au StringDictionary. Notez également que la ligne suivante:

myDict["foo"]

retournera null si myDictest a StringDictionary, mais une exception sera levée dans le cas de Dictionary<string, string>. Voir le message SO qu'il a mentionné pour plus d'informations, qui est la source de cette modification.

aréyle
la source
C'est exactement la question à laquelle j'ai lié.
Chris Morgan
1
Ha wow, je n'ai même pas compris ça - j'ai trouvé le même. Je ne pouvais pas modifier le commentaire, j'ai donc simplement modifié le message pour le résumer en un seul endroit. Merci!
areyling
1

Le problème avec votre exemple initial était principalement dû à l'utilisation de constplutôt questatic ; vous ne pouvez pas créer une référence const non nulle en C #.

Je pense que cela aurait également fonctionné:

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

De plus, comme le souligne Y Low, l'ajout readonlyest également une bonne idée, et aucun des modificateurs discutés ici n'empêchera le dictionnaire lui-même d'être modifié.

Charlie
la source
1

Créer un constructeur statique pour ajouter des valeurs dans le dictionnaire

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
la source
1
quire ou requête?
Ash
0

Rendez le dictionnaire statique et ne l'ajoutez jamais en dehors du ctor de votre objet statique. Cela semble être une solution plus simple que de jouer avec les règles static / const en C #.

Jeff Hubbard
la source
-1

Vous pouvez utiliser le constructeur static / class pour initialiser votre dictionnaire:

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
la source
1
Vouliez-vous rendre le dictionnaire statique? Vous ne pouvez pas l'avoir const. Comme le message d'erreur l'indique, seuls les types de valeur, les chaînes ou la valeur NULL peuvent être 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"} };             
    }
}

Initialisez probablement dans le constructeur.

Craig
la source