2008-11-24 3 views
74

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

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

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

+1

Вы не можете использовать сопзЬ со словарем типа, только со скалярными значениями. (проверьте мой ответ) http://msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx – Yona

ответ

173

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

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

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

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

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

+1

Но это не делает словарь только для чтения, просто это ссылка ... –

+0

Как насчет того, чтобы приватная статическая переменная класса была приватной статической Словарь <строка, строка> ErrorCodes, а затем в соответствующей функции проверяли if (ErrorCodes == null) { заполнить словарь} для кеширования при использовании в цикле? – Prathyush

+0

Если вы не хотите, чтобы словарь был изменен, вы можете перенести его в «ReadOnlyDictionary». Более эффективный (но менее безопасный вариант) - это присвоение ему типа IReadOnlyDictionary. –

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

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

-1

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

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

Вы имели в виду сделать словарь static? Вы не можете иметь его const. Как сказано в сообщении об ошибке, только значения типов, строк или нуля могут быть const –

0

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

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

Но это не мешает классу-потребителю изменять содержимое. – Everts

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

Это правильный синтаксис, который может скомпилировать – Graviton

0

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

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

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

4

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

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

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

myDict["foo"] 

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

+2

[Почему вы используете 'StringDictionary', а не' Dictionary '?] (Http://stackoverflow.com/questions/627716/stringdictionary-vs-dictionarystring-string) –

+0

Именно этот вопрос я и связывал. –

+1

Ха-вау, даже не поймал это - просто случилось найти то же самое. Я не мог отредактировать комментарий, поэтому я просто отредактировал сообщение, чтобы подвести итог в одном месте. Благодаря! – areyling

1

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

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

запрос или запрос? – Ash

Смежные вопросы