Search code examples
.netdictionaryobjectsystem.reflection

Object vs dictionary performance .NET


I wish to store information in the propertyname-property format, and I was wondering whether I should use an object or Dictionary. The object allows me flexibility in the value types, where the properties might be age and name and nationality and have values that differ in type, making dictionaries inconvenient and requiring large amounts of calling Convert.ToInt32.

On the other hand, if I make them objects, then I will need to access the properties by names, and I will also need to find random properties' names frequently. Reflection is costly for the system, and I've had no luck with delegates.

Performance is my key issue, and both ways to store Propertyname-property seem to have their downsides (with the dictionary accepting only one type of variable as value and the object necessitating reflection).

This will run in a much iterated over loop. Alternate solutions welcome

Thanks


Solution

  • I don't think that there is any competition for this. You want a run-time associative array - that's a dictionary.

    Here's how I would do it:

    public class Config
    {
        private Dictionary<Type, Dictionary<string, object>> _store
            = new Dictionary<Type, Dictionary<string, object>>();
    
        public void Store<T>(string key, T value)
        {
            if (!_store.ContainsKey(typeof(T)))
            {
                _store.Add(typeof(T), new Dictionary<string, object>());
            }
            _store[typeof(T)][key] = value;
        }
    
        public T Fetch<T>(string key)
        {
            return (T)_store[typeof(T)][key];
        }
    }
    

    Then you can write this code:

    var config = new Config();
    
    config.Store<int>("Life", 42);
    config.Store<string>("Hello", "World");
    
    int x = config.Fetch<int>("Life");
    string y = config.Fetch<string>("Hello");
    
    Console.WriteLine(x);
    Console.WriteLine(y);
    

    That outputs:

    42
    World
    

    All strongly-typed and very fast.

    Of course, this is a quickly thrown together class. You'd need to make sure that you flesh it out properly. How should you handle the situation when you have missing keys? Throwing an exception is generally not the best idea. I'd look at implementing public bool TryFetch<T>(string key, out T value) at least. Then you're not relying on exceptions.

    Perhaps try these methods:

        public bool TryFetch<T>(string key, out T value)
        {
            var success = _store.ContainsKey(typeof(T)) && _store[typeof(T)].ContainsKey(key);
            value = success ? this.Fetch<T>(key) : default(T);
            return success;
        }
    
        public bool TryInject<T>(string key, Action<T> inject)
        {
            var success = this.TryFetch<T>(key, out T value);
            if (success)
            {
                inject(value);
            }
            return success;
        }