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

Как объявить статический объект словаря в статическом классе? Я попробовал

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

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

Ответ 1

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

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

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

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

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

Ответ 2

Правильный синтаксис (как проверено в 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"} };
    }
}

Ответ 3

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

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

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

myDict["foo"]

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

Ответ 4

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

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

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

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

Ответ 5

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

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

Ответ 6

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

Ответ 7

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

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

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

Ответ 8

Вы можете использовать конструктор 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"} };
    }
}

Ответ 9

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

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