【问题标题】:C#: Using a generic dictionary <key, object> to hold settings of mixed type and return correct value and typecastC#:使用通用字典 <key, object> 保存混合类型的设置并返回正确的值和类型转换
【发布时间】:2015-02-26 22:43:26
【问题描述】:

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

【问题讨论】:

  • 为什么不只使用一个类?

标签: c# dictionary casting object-type


【解决方案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)

【讨论】:

  • 这似乎正是我想要的!我将尝试使用这个概念,看看它是否适用于我的想法。谢谢。
【解决方案2】:

您可以编写一个通用方法来访问字典,但是您需要在每次访问它时指定您想要的类型 - 它最终可能难以维护并且有问题。

感觉就像您已经按照自己的解决方案完成了工作,以至于您需要做更多的工作来维护它,而不仅仅是编写设置类。

一个类将是

  • 存储更紧凑
  • 访问速度更快
  • 更多类型安全
  • 在编码时更容易枚举 (Intellisense)
  • 支持在设置结构或命名更改时进行重构

当您开始遇到解决方案的问题时,有时值得重新开始并考虑是否有更简单的方法。

【讨论】:

    【解决方案3】:

    您可以创建一个类来为您处理转换。大致如下:

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

    【讨论】:

    • 我想你会发现它比Dictionary&lt;string, dynamic&gt; 的优势为零。您实际上是在通用 Get&lt;T&gt; 方法中重新实现了 dynamic 的一些行为。此外,通过返回 default(T) 来隐藏不良演员表似乎是不可取的。
    • 这很公平,代码只是为了让您了解类的外观。编辑代码以引发异常。
    猜你喜欢
    • 1970-01-01
    • 2015-06-01
    • 1970-01-01
    • 2011-12-24
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    • 2020-03-01
    相关资源
    最近更新 更多