我有一个5-6个字段的类,应该在构造函数运行后初始化一次。
public OriginalFileProcessor(IConfigManager configManager)
{
this._configManager = configManager;
this._field1 = this._configManager.GetAppSetting<int>ConfigKeys.Key1);
this._field2 = this._configManager.GetAppSetting<int>ConfigKeys.Key2);
this._field3 = this._configManager.GetAppSetting<int>ConfigKeys.Key3);
this._field4 = this._configManager.GetAppSetting<int>ConfigKeys.Key4);
this._field5 = this._configManager.GetAppSetting<int>ConfigKeys.Key5);
}
但我不喜欢在构造函数中仅仅编写简单的赋值来编写逻辑。
我不能对field1使用内联初始化,例如,因为那时我不能在那里使用_configManager实例:
private int readonly _field1 = this._configManager.GetAppSetting<int>ConfigKeys.Key1);
如果我使用readonly属性,那么我必须添加这样的额外代码:
private int? _field1;
public int Property1
{
get
{
if (!this._field1.HasValue)
{
this.__field1 = this._configManager.GetAppSetting<int>(Key1);
}
return this._field1.Value;
}
}
是否有更简单的方法来进行实例字段的后期初始化?
答案 0 :(得分:5)
Lazy<T>
是建议的好选择。
我通常使用以下内容......
提供_field*
是nullable
在你的财产中你可以做...
return this.__field1 ?? (this.__field1 = this._configManager.GetAppSetting<int>(Key1));
编辑:
鉴于评论讨论 - 为什么不使用non static approach
而不是Lazy<T>
,例如
private readonly Lazy<int?> _field;
// init in ctor
_field = new Lazy<int?>(() => YourFieldInit(""));
// use in property
return _field.Value ?? 0;
编辑2:
一个小小的测试来澄清懒惰的行为:
public class DoLazy
{
Lazy<int?> _field;
public DoLazy()
{
// 'lazy' gets initialized - but `YourFieldInit` is not called yet.
_field = new Lazy<int?>(() => YourFieldInit(""));
}
int Property
{
get
{
// `YourFieldInit` is called here, first time.
return _field.Value ?? 0;
}
}
int? YourFieldInit(string test)
{ // breakpoint here
return -1;
}
public static void Test()
{
var lazy = new DoLazy();
int val1 = lazy.Property;
var val = lazy.Property;
}
}
在YourFieldInit
内放置一个断点 - 以查看它实际被调用的时间
从您的电话中拨打DoLazy.Test()
主要。