简体   繁体   English

C#:使用通用字典 <key, object> 保持混合类型的设置并返回正确的值和类型转换

[英]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...). 有几种可能的设置列表,包括几种类型的设置(int,double,string等...)。 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. 但我试图避免为每个可能的设置键入Get和Set。 Is there an elegant solution (even that may involve typing a little more code) that any one can share? 是否有一个优雅的解决方案(甚至可能涉及输入更多代码),任何人都可以分享?

For a quick and lightweight solution, you should consider using a dynamic value type: 对于快速轻量级的解决方案,您应该考虑使用dynamic值类型:

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) 您可以在此处阅读有关dynamic更多信息: 使用Type dynamic (C#编程指南)

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. 你可以编写一个通用的方法来访问Dictionary,但是你需要在每次访问时指定你想要的类型 - 它最终可能难以维护和错误。

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) 编码时更容易枚举(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. 当您开始遇到解决方案的问题时,有时值得回到起点并考虑是否有更简单的方法。

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)));
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM