Deklarieren Sie ein Wörterbuch innerhalb einer statischen Klasse

90

Wie deklariere ich ein statisches Wörterbuchobjekt innerhalb einer statischen Klasse? Ich habe es versucht

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

Der Compiler beschwert sich jedoch darüber, dass " ein const-Feld eines anderen Referenztyps als string nur mit null initialisiert werden kann ".

Graviton
quelle
1
Sie können const nicht mit dem Dictionary-Typ verwenden, sondern nur mit skalaren Werten. (Überprüfen Sie meine Antwort) msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx
Yona

Antworten:

214

Wenn Sie das Wörterbuch einmal deklarieren und niemals ändern möchten, deklarieren Sie es als schreibgeschützt:

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

Wenn Sie Wörterbuchwörterbücher schreibgeschützt machen möchten (nicht nur die Referenz, sondern auch die Elemente in der Sammlung), müssen Sie eine schreibgeschützte Wörterbuchklasse erstellen, die IDictionary implementiert.

Schauen Sie sich ReadOnlyCollection als Referenz an.

BTW const kann nur verwendet werden, wenn Skalarwerte inline deklariert werden.

Yona
quelle
Wie wäre es mit einer privaten statischen Variablen auf Klassenebene, einem privaten statischen Wörterbuch <string, string> ErrorCodes und dann in der jeweiligen Funktion zu überprüfen, ob (ErrorCodes == null) {Wörterbuch füllen} den Wert zwischenspeichert, wenn es in einer Schleife verwendet wird?
LifeOfPi
1
Wenn Sie nicht möchten, dass das Wörterbuch geändert wird, können Sie es in ein Wörterbuch einbinden ReadOnlyDictionary. Eine effizientere (aber weniger sichere) Option besteht darin, sie einem IReadOnlyDictionaryTyp zuzuweisen .
Ramon de Klein
8

Die korrekte Syntax (wie in VS 2008 SP1 getestet) lautet:

public static class ErrorCode
{
    public static IDictionary<string, string> ErrorCodeDic;
     static ErrorCode()
    {
        ErrorCodeDic = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
    }
}
Graviton
quelle
Dies verhindert jedoch nicht, dass eine konsumierende Klasse den Inhalt ändert.
Everts
4

Alte Frage, aber ich fand das nützlich. Es stellt sich heraus, dass es auch eine spezielle Klasse für ein Wörterbuch gibt, die eine Zeichenfolge sowohl für den Schlüssel als auch für den Wert verwendet:

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

Bearbeiten: Gemäß Chris 'Kommentar unten wird die Verwendung von Dictionary<string, string>over StringDictionaryim Allgemeinen bevorzugt, hängt jedoch von Ihrer Situation ab. Wenn Sie mit einer älteren Codebasis arbeiten, sind Sie möglicherweise auf die beschränkt StringDictionary. Beachten Sie auch die folgende Zeile:

myDict["foo"]

gibt null zurück, wenn a myDictist StringDictionary, aber im Fall von wird eine Ausnahme ausgelöst Dictionary<string, string>. Sehen Sie sich die SO Post erwähnte er für weitere Informationen, die die Quelle dieser bearbeiten ist.

Areyling
quelle
Das ist genau die Frage, mit der ich verbunden bin.
Chris Morgan
1
Ha wow, habe das nicht mal verstanden - habe zufällig das gleiche gefunden. Ich konnte den Kommentar nicht bearbeiten, also habe ich den Beitrag nur bearbeitet, um ihn an einer einzigen Stelle zusammenzufassen. Vielen Dank!
Areyling
1

Das Problem mit Ihrem ersten Beispiel war hauptsächlich auf die Verwendung von constanstatt zurückzuführen static. Sie können in C # keine Nicht-Null-Konstantenreferenz erstellen.

Ich glaube, das hätte auch funktioniert:

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

Wie Y Low hervorhebt, ist das Hinzufügen ebenfalls readonlyeine gute Idee, und keiner der hier diskutierten Modifikatoren verhindert, dass das Wörterbuch selbst geändert wird.

Charlie
quelle
1

Erstellen Sie einen statischen Konstruktor, um Werte im Wörterbuch hinzuzufügen

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
quelle
1
fragen oder fragen?
Ash
0

Machen Sie das Wörterbuch zu einem statischen Wörterbuch und fügen Sie es niemals außerhalb des Ctors Ihres statischen Objekts hinzu. Das scheint eine einfachere Lösung zu sein, als mit den statischen / const-Regeln in C # herumzuspielen.

Jeff Hubbard
quelle
-1

Sie können den statischen / Klassenkonstruktor verwenden, um Ihr Wörterbuch zu initialisieren:

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
quelle
1
Wollten Sie das Wörterbuch statisch machen? Sie können es nicht const haben. Wie die Fehlermeldung besagt, können nur Werttypen, Zeichenfolgen oder Null konstant sein
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"} };             
    }
}

Wahrscheinlich im Konstruktor initialisieren.

Craig
quelle