除非您对默认值属性有其他用途,否则我将避免使用整个反射方法,而是使用一个执行值转换的扩展类,并在其中提供默认值。可以将类型转换直接捆绑到扩展方法中,以避免对
Convert.ToXXX()
.
public static class DictionaryExt
{
// bundles up safe dictionary lookup with value conviersion...
// could be split apart for improved maintenance if you like...
public static TResult ValueOrDefault<TKey,TValue,TResult>(
this DIctionary<TKey,TValue> dictionary, TKey key, TResult defaultVal )
{
TValue value;
return dictionary.TryGetValue( key, out value )
? Convert.ChangeType( value, typeof(TResult) )
: defaultVal;
}
}
现在,您的配置类可以是:
public class MyTaskConfigurationWrapper : ConfigurationWrapper
{
private const string MyIntPropertyKey = "MyIntProperty";
int MyIntProperty
{
// supply the default as a parameter, not reflection attribute
get {
return _config.ValueOrDefault( MyIntPropertyKey, 7 ); }
set {
_config[MyIntPropertyKey] = value.ToString(CultureInfo.InvarientCulture); }
}
// More properties of various types.
}
此方法允许您为没有方便的编译时表示形式(如日期时间、时间跨度、点等)的类型提供默认值。它还避免了所有混乱的反射逻辑。
如果需要通过基类访问默认值,那么可能需要使用反射/属性方法。但是,即使是,也可以通过迭代所有公共属性并访问它们的getter在创建时获取默认值来用默认值初始化值字典。