116

How to declare a static dictionary object inside a static class? I tried

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

But the compiler complains that "A const field of a reference type other than string can only be initialized with null".

Graviton
  • 81,782
  • 146
  • 424
  • 602
  • 1
    You cannot use const with the Dictionary type, only with scalar values. (check my answer) http://msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx – Yona Nov 24 '08 at 03:32

10 Answers10

260

If you want to declare the dictionary once and never change it then declare it as readonly:

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

If you want to dictionary items to be readonly (not just the reference but also the items in the collection) then you will have to create a readonly dictionary class that implements IDictionary.

Check out ReadOnlyCollection for reference.

BTW const can only be used when declaring scalar values inline.

Yona
  • 9,392
  • 4
  • 33
  • 42
  • How about having a class level private static variable private static Dictionary ErrorCodes and then in respective function check if(ErrorCodes == null) { fill dictionary} to cache value when used in loop? – LifeOfPi Feb 28 '17 at 14:14
  • 1
    If you don't want the dictionary to be changed, then you can wrap it into a `ReadOnlyDictionary`. A more efficient (but less safe option) is to assign it to a `IReadOnlyDictionary` type. – Ramon de Klein Mar 29 '18 at 09:06
8

The correct syntax ( as tested in VS 2008 SP1), is this:

public static class ErrorCode
{
    public static IDictionary<string, string> ErrorCodeDic;
     static ErrorCode()
    {
        ErrorCodeDic = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
    }
}
Graviton
  • 81,782
  • 146
  • 424
  • 602
5

Old question, but I found this useful. Turns out, there's also a specialized class for a Dictionary using a string for both the key and the value:

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

Edit: Per Chris's comment below, using Dictionary<string, string> over StringDictionary is generally preferred but will depend on your situation. If you're dealing with an older code base, you might be limited to the StringDictionary. Also, note that the following line:

myDict["foo"]

will return null if myDict is a StringDictionary, but an exception will be thrown in case of Dictionary<string, string>. See the SO post he mentioned for more information, which is the source of this edit.

Community
  • 1
  • 1
areyling
  • 2,181
  • 2
  • 20
  • 25
  • 2
    [Why would you use `StringDictionary` rather than `Dictionary`?](http://stackoverflow.com/questions/627716/stringdictionary-vs-dictionarystring-string) – Chris Morgan Dec 03 '12 at 00:57
  • That's exactly the question I linked to. – Chris Morgan Dec 03 '12 at 01:47
  • 1
    Ha wow, didn't even catch that--just happened to find the same one. I couldn't edit the comment, so I just edited the post to summarize in a single place. Thanks! – areyling Dec 03 '12 at 14:50
3

Create a static constructor to add values in the Dictionary

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

Make the Dictionary a static, and never add to it outside of your static object's ctor. That seems to be a simpler solution than fiddling with the static/const rules in C#.

Jeff Hubbard
  • 9,822
  • 3
  • 30
  • 28
1

The problem with your initial example was primarily due to the use of const rather than static; you can't create a non-null const reference in C#.

I believe this would also have worked:

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

Also, as Y Low points out, adding readonly is a good idea as well, and none of the modifiers discussed here will prevent the dictionary itself from being modified.

Charlie
  • 44,214
  • 4
  • 43
  • 69
0

OK - so I'm working in ASP 2.x (not my choice...but hey who's bitching?).

None of the initialize Dictionary examples would work. Then I came across this: http://kozmic.pl/archive/2008/03/13/framework-tips-viii-initializing-dictionaries-and-collections.aspx

...which hipped me to the fact that one can't use collections initialization in ASP 2.x.

jray
  • 1,226
  • 9
  • 9
0

You can use the static/class constructor to initialize your dictionary:

public static class ErrorCode
{
    public const IDictionary<string, string> ErrorCodeDic;
    public static ErrorCode()
    {
        ErrorCodeDic = new Dictionary<string, string>()
            { {"1", "User name or password problem"} };
    }
}
Andy
  • 30,088
  • 6
  • 78
  • 89
  • 1
    Did you mean to make the dictionary static? You can't have it const. As the error message says, only value types, strings, or null can be const – Orion Edwards Nov 24 '08 at 03:56
0

Use a public static property dictionary and wrap the static private dictionary inside. Then you only need to take care about mutable or immutable types, first one you need to iterate inside the wrapper. That allows you to read a dictionary, but not edit it (not the entries and not the whole reference) with the option to allow edit inside the set{} part using any authentication model you prefer.

(I was looking for something different, like static performance in parallel coding, saw this search result and find the wrapper approach missing.)

For those who don't know what wrapping is, here a non static example (you can easily add the static key-word):

public Dictionary<string, Boolean> Access
{
    get
    {
        // Same here, iterate if needed..
        return new Dictionary<string, Boolean>(prv_Access);
    }
    set
    {
        MainWindow.NewSession.Renew();
        if (MainWindow.NewSession.Actual)
        {
            prv_HistoryAccess.Add(DateTime.Now, new Dictionary<string, Boolean>(prv_Access));

            // Here you would need to iterate when you deal with mutables..
            prv_Access = value;
        }
    }
}
Dororo
  • 41
  • 4
-3
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"} };             
    }
}

Probably initialise in the constructor.

Craig
  • 36,306
  • 34
  • 114
  • 197