我正在尝试实现一个类,以优雅且易于维护的方式保存用户设置。有一个广泛的可能设置列表,包括几种类型的设置(int、double、string等)。我试图使用字典,但由于我的类型是混合的,我使用泛型对象类型作为键返回值。我还有另一本字典,里面有与每个设置相关的类型供参考。我的问题是,我希望创建一个查找函数,它不仅返回特定的设置值,而且还将其正确地转换为适当的类型。由于我的字典包含对象类型,所以我的函数也必须返回对象类型。但我尽量避免为每种可能的设置键入Get和Set。有没有一个任何人都可以共享的优雅解决方案(甚至可能需要键入更多的代码)?
对于快速、轻量级的解决方案,您应该考虑使用dynamic
值类型:
var settings = new Dictionary<string, dynamic>();
settings["FavoriteWidget"] = "Gizmo";
settings["Weight"] = 0.5
string favoriteWidget = settings["FavoriteWidget"];
double weight = settings["Weight"];
您可以在这里阅读更多关于dynamic
的信息:使用类型dynamic
(C#编程指南)
您可以编写一个通用方法来访问Dictionary,但每次访问时都需要指定您想要的类型——这可能会导致维护困难和出现错误。
感觉就像你已经遵循了你的解决方案,以至于你要做更多的工作来维护它,而不仅仅是编写一个设置类。
一个等级将是
- 存储更紧凑
- 访问速度更快
- 更安全的类型
- 编码时更容易枚举(Intellisense)
- 如果设置结构或命名发生更改,则支持重构
当你开始在解决方案中遇到问题时,有时值得回到最初,考虑是否有更简单的方法。
您可以创建一个类来处理转换。大致如下:
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)));
}
}
}