1

I am currently struggling to create a dictionary. I want to create it so that it can be used in multiple situations. However, these situations vary from key and value types. So while you normally do:

Dictionary<int, string> Something = new Dictionary<int, string>();

I want to do something like:

Dictionary<variable1, variable2> ..............

Doesn't matter much what variable1 is. It can be a string, that stores 'string', or 'int' as value. I could also use variable1.getType() to determine the type. Either way would work for me. But the way I did above, well, that is just incorrect. There must be another way to set the key and value type based on variables... right?

Something just shoot into my head, to use if's to check what the type is, and based on the type make the dictionary use that type. But with the amount of types, it's going to be a lot of if's, and I feel like there has to be a better way.

Searching hasn't helped me much. Well I learned some other things, but no solution to my problem. In every single case, dictionary TKey and TValue has been set manually. While I want to set them, with a variable that I take from some source.

Tim S. Van Haren
  • 8,861
  • 2
  • 30
  • 34
Verkade89
  • 373
  • 2
  • 12
  • I guess this has been answered already [Here](http://stackoverflow.com/a/3086222/4366237) – Umair M Jul 12 '15 at 22:55
  • Create a class for the key and store all the fields you want for it, inside the key class. Th – Gilad Jul 12 '15 at 23:00
  • Why do you want to do this? I think you have an XY problem. See http://meta.stackexchange.com/a/66378/144156 – Enigmativity Jul 12 '15 at 23:17
  • @Enigmativity Why I wanna do this? I am trying to create a dictionary that holds indexes (keys) and row-data (class). Now these indexes are of different types. Most are integers, like IDs. But some cases the keys are a string. Now I am trying to get multiple tables out of the database, the application is reading the structure and now comes the point where the application is creating everything based on the information he received. So that I don't have to write out everything, or in case of a change, that I have to change the database and application. – Verkade89 Jul 12 '15 at 23:43
  • @Verkade89 - Then it sounds like you need `Dictionary` (whatever `row-data` may actually be). – Enigmativity Jul 12 '15 at 23:53

3 Answers3

5

There must be another way to set the key and value type based on variables... right?

Yes, there is. You can make a helper method that creates a dictionary, example:

public static Dictionary<K, V> CreateDictionaryFor<K, V>(K key, V value)
{
    return new Dictionary<K, V>();
}

Then, you can use it with variable1 and variable2:

var dictionary = CreateDictionaryFor(variable1, variable2);
Dzienny
  • 3,295
  • 1
  • 20
  • 30
  • That works wonders indeed. I am getting the right dictionary back from CreateDictionaryFor. Strange tho, that it has to be done that way, and (can't) be done directly. – Verkade89 Jul 12 '15 at 23:18
2

You can try doing Dictionary<object, object>.

That way you can pass whatever you need to pass and check the type as needed.

var dict = new Dictionary<object, object>();

dict.Add(45, "dkd");
scartag
  • 17,548
  • 3
  • 48
  • 52
  • are you sure object will work? for all types? i dont think so. – M.kazem Akhgary Jul 12 '15 at 22:26
  • 2
    @M.kazemAkhgary All types inherit from `object` so it will. – Dzienny Jul 12 '15 at 22:27
  • nice. the way i was thinking was using dynamic. but it seems object works. but you have to always cast a given value. – M.kazem Akhgary Jul 12 '15 at 22:33
  • @M.kazemAkhgary thats part of his requirements .. he's not worried about calling `GetType` for each instance. – scartag Jul 12 '15 at 22:35
  • It is indeed one solution. However, I noticed that the memory usage went up by quite a bit by using this, and that's a little bit worrying. As the dictionary contains a lot of key/values. – Verkade89 Jul 12 '15 at 22:35
  • @Verkade89 I think the content is where the memory issue is and not the type you chose to use (object in this case) – scartag Jul 12 '15 at 22:36
  • and you can add objects of different types in the same dictionary - could also be a problem... – Philip W Jul 12 '15 at 22:38
  • That too, yes. Large amount of anything ends up in a lot of memory. But in this case, changing from short to object resulted in 861MB to 1.107MB memory usage. And as the types are known, well... it would be a shame to not create a dictionary with that type. That's what I am trying to accomplish. – Verkade89 Jul 12 '15 at 22:43
  • @Verkade89 I guess thats why ... price to pay for the added convenience of putting any type .. (i wouldn't call it a convenience though). – scartag Jul 12 '15 at 22:45
  • @Verkade89 It happens because the `short` gets boxed ie changed from a value type to a reference type. This process additionaly hurts performance. – Dzienny Jul 12 '15 at 22:49
  • I might be missing the point here. Can you explain more about what you are trying to achieve? – Corey Jul 12 '15 at 23:32
1

A pssibility would be to capsulate the dictionary in a new class, and create the dictionary via a generic method:

public class GenericDictionary
{
    private IDictionary m_dictionary;

    public bool Add<TA, TB>(TA key, TB value)
    {
        try
        {
            if (m_dictionary == null)
            {
                m_dictionary = new Dictionary<TA, TB>();
            }

            //check types before adding, instead of using try/catch
            m_dictionary.Add(key, value);

            return true;
        }
        catch (Exception)
        {
            //wrong types were added to an existing dictionary
            return false;
        }
    }
}

Of course the code above needs some improvements (no exception when adding wrong types, additional methods implementing the dictionary methods you need), but the idea should be clear.

Philip W
  • 781
  • 3
  • 7