virtore
virtore

Reputation: 161

C#: Using a generic dictionary <key, object> to hold settings of mixed type and return correct value and typecast

I am trying to implement a class to hold user settings in an elegant and easy to maintain manner. There is an extensive list of possible settings with several types of settings(int, double, string etc...). I was trying to use a dictionary but since my types are mixed I used the generic object type as key return value. I also have another dictionary holding the type associated with each setting for reference. My problem is that I wish to create a lookup function that not only returns the specific setting value but also casts it correctly to the appropriate type. Since my dictionary holds object type, my function also has to return object type. But I am trying to avoid having to type out Get and Set for each possible setting. Is there an elegant solution (even that may involve typing a little more code) that any one can share?

Upvotes: 2

Views: 2155

Answers (3)

RagtimeWilly
RagtimeWilly

Reputation: 5445

You could create a class to handle the conversions for you. Something along the lines of:

public class Settings
{
    private Dictionary<string, object> _settings = new Dictionary<string, object>();

    public void Add(string key, object value)
    {
        _settings.Add(key, value);
    }

    public T Get<T>(string key)
    {
        if (!_settings.ContainsKey(key))
            throw new KeyNotFoundException(string.Format("Cannot find setting {0}", key));

        if (_settings[key] is T)
            return (T)_settings[key];

        try
        {
            return (T)Convert.ChangeType(_settings[key], typeof(T));
        }
        catch (InvalidCastException)
        {
            throw new InvalidCastException(string.Format("Unable to cast setting {0} to {1}", key, typeof(T)));
        }
    }
}

Upvotes: 1

Timothy Shields
Timothy Shields

Reputation: 79461

For a quick and lightweight solution, you should consider using a dynamic value type:

var settings = new Dictionary<string, dynamic>();
settings["FavoriteWidget"] = "Gizmo";
settings["Weight"] = 0.5

string favoriteWidget = settings["FavoriteWidget"];
double weight = settings["Weight"];

You can read more about dynamic here: Using Type dynamic (C# Programming Guide)

Upvotes: 6

TheEvilPenguin
TheEvilPenguin

Reputation: 5672

You could write a generic method to access the Dictionary, but then you'd need to specify which type you want each time you access it - it could end up difficult to maintain and buggy.

It feels like you've followed your solution through to the point that you're doing more work to maintain it than to just write a settings class.

A class will be

  • stored more compactly
  • accessed faster
  • more type safe
  • more easily enumerable while coding (Intellisense)
  • support refactoring if the settings structure or naming changes

When you start running into problems with a solution, sometimes it's worth going back to the start and considering if there's an easier way.

Upvotes: 4

Related Questions