首页 文章

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

提问于
浏览
2

我正在尝试实现一个类,以优雅和易于维护的方式保存用户设置 . 有几种可能的设置列表,有几种类型的设置(int,double,string等...) . 我试图使用字典,但由于我的类型是混合的,我使用通用对象类型作为键返回值 . 我还有另一个字典,其中包含与每个设置相关联的类型以供参考 . 我的问题是我希望创建一个查找函数,它不仅返回特定的设置值,还将其正确地转换为适当的类型 . 由于我的字典包含对象类型,我的函数也必须返回对象类型 . 但我试图避免为每个可能的设置键入Get和Set . 是否有一个优雅的解决方案(甚至可能涉及输入更多的代码),任何人都可以共享?

3 回答

  • 1

    对于快速轻量级的解决方案,您应该考虑使用 dynamic 值类型:

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

    你可以在这里阅读更多关于 dynamic 的内容:Using Type dynamic (C# Programming Guide)

  • 6

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

    感觉就像你已经按照你的解决方案进行了更多的工作来维护它,而不仅仅是编写一个设置类 .

    一堂课

    • 存储更紧凑

    • 访问速度更快

    • 更安全类型

    • 编码时更容易枚举(Intellisense)
      如果设置结构或命名发生更改,

    • 支持重构

    当您开始遇到解决方案的问题时,有时值得回到起点并考虑是否有更简单的方法 .

  • 4

    您可以创建一个类来处理转换 . 有点像:

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

相关问题