Zadeklaruj słownik wewnątrz klasy statycznej


90

Jak zadeklarować statyczny obiekt słownika w klasie statycznej? próbowałem

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

Jednak kompilator narzeka, że ​​„ Pole const typu referencyjnego innego niż łańcuch może być zainicjowane tylko wartością null ”.


1
Nie możesz używać const z typem Dictionary, tylko z wartościami skalarnymi. (sprawdź moją odpowiedź) msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx
Yona,

Odpowiedzi:


214

Jeśli chcesz raz zadeklarować słownik i nigdy go nie zmieniać, zadeklaruj go jako tylko do odczytu:

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

Jeśli chcesz, aby elementy ze słownika były tylko do odczytu (nie tylko jako odniesienie, ale także elementy w kolekcji), musisz utworzyć klasę słownika tylko do odczytu, która implementuje IDictionary.

Sprawdź ReadOnlyCollection w celach informacyjnych.

BTW const może być używane tylko podczas deklarowania wartości skalarnych w tekście.


Co powiesz na posiadanie prywatnej zmiennej statycznej na poziomie klasy, prywatnej statycznej zmiennej Dictionary <string, string> ErrorCodes, a następnie w odpowiedniej funkcji sprawdzić, czy (ErrorCodes == null) {wypełnij słownik}, aby buforować wartość, gdy jest używana w pętli?
LifeOfPi

1
Jeśli nie chcesz, aby słownik był zmieniany, możesz umieścić go w pliku ReadOnlyDictionary. Bardziej wydajną (ale mniej bezpieczną opcją) jest przypisanie jej do IReadOnlyDictionarytypu.
Ramon de Klein

8

Prawidłowa składnia (zgodnie z testami w VS 2008 SP1) jest następująca:

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

Nie przeszkadza to jednak klasie konsumującej w modyfikowaniu zawartości.
Everts

4

Stare pytanie, ale uznałem to za przydatne. Okazuje się, że istnieje również wyspecjalizowana klasa dla Dictionary, która używa ciągu znaków zarówno dla klucza, jak i wartości:

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

Edycja: Zgodnie z komentarzem Chrisa poniżej, używanie Dictionary<string, string>over StringDictionaryjest generalnie preferowane, ale zależy od twojej sytuacji. Jeśli masz do czynienia ze starszą bazą kodu, możesz być ograniczony do StringDictionary. Zwróć również uwagę, że następujący wiersz:

myDict["foo"]

zwróci wartość null, jeśli myDictjest a StringDictionary, ale zostanie zgłoszony wyjątek w przypadku Dictionary<string, string>. Zobacz wpis SO, o którym wspomniał, aby uzyskać więcej informacji, który jest źródłem tej zmiany.



To jest dokładnie pytanie, z którym się połączyłem.
Chris Morgan,

1
Ha wow, nawet tego nie złapałem - po prostu znalazłem to samo. Nie mogłem edytować komentarza, więc po prostu zredagowałem post, aby podsumować go w jednym miejscu. Dzięki!
wylatuje

1

Problem z twoim początkowym przykładem wynikał głównie z użycia constzamiast static; nie można utworzyć odwołania do const niezerowego w języku C #.

Myślę, że to również zadziałałoby:

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

Ponadto, jak wskazuje Y Low, dodawanie readonlyjest również dobrym pomysłem i żaden z omawianych tutaj modyfikatorów nie uniemożliwi modyfikacji samego słownika.


1

Utwórz konstruktor statyczny, aby dodać wartości w słowniku

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
quire or quire?
Ash

0

Możesz użyć konstruktora static / class, aby zainicjować swój słownik:

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
Czy chodziło Ci o to, aby słownik był statyczny? Nie możesz mieć tego const. Jak mówi komunikat o błędzie, tylko typy wartości, ciągi lub null mogą być stałymi
Orion Edwards,

0

Stwórz słownik jako statyczny i nigdy nie dodawaj do niego poza ctorem obiektu statycznego. Wydaje się, że jest to prostsze rozwiązanie niż majstrowanie przy regułach statycznych / stałych w C #.



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

Prawdopodobnie zainicjalizuj w konstruktorze.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.