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


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.


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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.