Search code examples
c#dictionaryenums

Can you use Classes as values in a dictionary


Fairly new to programming, and I am trying to make an id system, which is basically:

...
     enum ids
     {
          id1,
          id2,
          id3
     }

     Dictionary<ids, _____> IdDictionary = new Dictionary<ids, _____>()
     { 
           {0, Id1Class}
           {1, Id2Class}
           {2, Id3Class}
     }

class Id1Class
{
     //some data
}

class Id2Class
{
     //some data
}

class Id3Class
{
     //some data
}
...

That's want I want to do. The idea is that an enum contains the Id, and the dictionary assigns the data types (in this case, I am trying to make province system, so for say a random one in say... Germany, the enum would assign the id, and using the id, the dictionary would set it to that province, with things like population and such). I assumed that this would be a way to do it, but it doesn't seem to work. I'm not sure what to put in the part declaring the type of the dictionary's values. Maybe the namespace or something? Or make it a method or something? Not sure.

I want IdDictionary[ids.id1] to return the class Id1Class.


Solution

  • Sure you can! Here you go:

    public static void Main()
    {
        Dictionary<ids, Type> IdDictionary = new Dictionary<ids, Type>()
        { 
           {ids.id1, typeof(Id1Class)},
           {ids.id2, typeof(Id2Class)},
           {ids.id3, typeof(Id3Class)}
        };
        
        Console.WriteLine(IdDictionary[ids.id1]);
        Console.WriteLine(IdDictionary[ids.id2]);
        Console.WriteLine(IdDictionary[ids.id3]);
    }
    

    Output:

    Program+Id1Class
    Program+Id2Class
    Program+Id3Class
    

    Explanation:

    The problem you were running into is that you wanted to use the classes themselves as the values for the dictionary, not individual instances/objects of those classes. When you're first introduced to dictionaries, this may not be explained yet.

    To do this, you need to take these classes and treat them as individual objects, rather than overall types. In C#, classes (as well as other things, such as structs) are themselves instances of Type. So to treat a class as an instance, you can use typeof(<ClassName>), and you will get the object representation of that class.

    So in your example above:

    1. The second generic parameter to the dictionary should be Type.
    2. Dictionary itself should be capitalized.
    3. typeof(Id1Class), typeof(Id2Class), and typeof(Id3Class) should be used to get the object/instance representations of those classes. In that way, you can pass the classes around like ordinary data, using them as arguments to functions and whatever else you want. In this case, you can do this to populate your dictionary.
    4. Forgot to mention: Also use things like ids.id1 and ids.id2, instead of things like 0 and 1. Sipo reminded me by including this point in their (upvoted) answer.