Объявить словарь внутри статического класса

90

Как объявить объект статического словаря внутри статического класса? Я старался

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

Но компилятор жалуется, что « константное поле ссылочного типа, отличного от строки, может быть инициализировано только нулевым значением ».

Гравитон
источник
1
Вы не можете использовать const с типом Dictionary, только со скалярными значениями. (проверьте мой ответ) msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx
Йона,

Ответы:

215

Если вы хотите объявить словарь один раз и никогда не менять его, объявите его как readonly:

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

Если вы хотите, чтобы элементы словаря были доступны только для чтения (не только для ссылки, но и для элементов в коллекции), вам необходимо создать класс словаря только для чтения, который реализует IDictionary.

Ознакомьтесь с ReadOnlyCollection для справки.

BTW const можно использовать только при объявлении скалярных значений встроенными.

Йона
источник
Как насчет того, чтобы иметь частную статическую переменную уровня класса private static Dictionary <string, string> ErrorCodes, а затем в соответствующей функции проверить, если (ErrorCodes == null) {fill dictionary} кэшировать значение при использовании в цикле?
LifeOfPi
1
Если вы не хотите, чтобы словарь изменялся, вы можете обернуть его в ReadOnlyDictionary. Более эффективный (но менее безопасный вариант) - назначить его IReadOnlyDictionaryтипу.
Ramon de Klein
8

Правильный синтаксис (проверенный в VS 2008 SP1) таков:

public static class ErrorCode
{
    public static IDictionary<string, string> ErrorCodeDic;
     static ErrorCode()
    {
        ErrorCodeDic = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
    }
}
Гравитон
источник
Но это не мешает потребляющему классу изменять контент.
Everts
4

Старый вопрос, но я нашел это полезным. Оказывается, есть также специализированный класс для словаря, использующий строку как для ключа, так и для значения:

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

Изменить: Согласно приведенному ниже комментарию Криса, использование Dictionary<string, string>over StringDictionaryобычно предпочтительно, но будет зависеть от вашей ситуации. Если вы имеете дело со старой базой кода, вы можете ограничиться расширением StringDictionary. Также обратите внимание, что следующая строка:

myDict["foo"]

вернет null, если myDictэто a StringDictionary, но в случае Dictionary<string, string>. См. Сообщение SO, которое он упомянул, для получения дополнительной информации, которая является источником этого редактирования.

арейлинг
источник
Это именно тот вопрос, с которым я связался.
Крис Морган
1
Ха, ничего себе, даже не уловил - просто случайно нашел такую ​​же. Я не мог редактировать комментарий, поэтому просто отредактировал сообщение, чтобы подвести итог в одном месте. Благодаря!
areyling 03
2

Создайте статический конструктор для добавления значений в Словарь

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
запрос или запрос?
Эш
1

Проблема с вашим первоначальным примером была связана, прежде всего, с использованием, constа не static; вы не можете создать ненулевую ссылку на константу в C #.

Я считаю, что это тоже сработало бы:

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

Кроме того, как указывает Y Low, добавление также readonlyявляется хорошей идеей, и ни один из обсуждаемых здесь модификаторов не предотвратит изменение самого словаря.

Чарли
источник
0

Вы можете использовать конструктор static / class для инициализации вашего словаря:

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
Вы хотели сделать словарь статичным? У вас не может быть const. Как говорится в сообщении об ошибке, константами могут быть только типы значений, строки или null
Орион Эдвардс
0

Сделайте словарь статическим и никогда не добавляйте в него за пределами ctor вашего статического объекта. Это кажется более простым решением, чем возиться со статическими / константными правилами в C #.

Джефф Хаббард
источник
0

ОК - значит, я работаю в ASP 2.x (не мой выбор ... но эй, кто скулит?).

Ни один из примеров инициализации словаря не будет работать. Потом я наткнулся на это: http://kozmic.pl/archive/2008/03/13/framework-tips-viii-initializing- dictionaries-and-collections.aspx

... что убедило меня в том, что нельзя использовать инициализацию коллекций в ASP 2.x.

jray
источник
-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"} };             
    }
}

Вероятно, инициализируйте в конструкторе.

Крейг
источник