在属性中执行初始化是一个好习惯吗?
本文关键字:一个 好习惯 属性 执行 初始化 | 更新日期: 2023-09-27 18:17:28
我有一个类PluginProvider,它使用PluginLoader组件从文件系统加载插件(managed/native)。在PluginProvider类中,目前定义了一个名为'PluginTypes'的属性,它在get()上调用'InitializePlugins'实例方法。
class PluginProvider
{
IEnumerable<IPluginType> PluginTypes
{
get
{
//isInitialized is set inside InitializePlugins method
if(!isInitialized)
{
InitializePlugins(); //contains thread safe code
}
//_pluginTypes is set within InitializePlugins method
return _pluginTypes;
}
}
}
我正在考虑重构这段代码。我想知道在属性中进行这种初始化是否合适。我知道不能在物业内进行繁重的操作。但是当我检查这个链接:http://msdn.microsoft.com/en-us/library/vstudio/ms229054.aspx时,发现这个"特别是,访问网络或文件系统的操作(除了一次初始化)应该很可能是方法,而不是属性。"现在我有点困惑了。请帮助。
- 如果你想尽可能延迟初始化,并且你不知道何时你的属性(或属性)将被调用,你所做的是好的。
- 如果你想延迟并且你可以控制何时你的属性将被第一次调用,那么你可能想让你的方法
InitializePlugins()
公开,并在访问属性之前显式调用它。此选项还提供了异步初始化的可能性。例如,您可以让一个InitializePluginsAsync()
返回一个Task
。 如果延迟初始化不是一个大问题,那么只需在构造函数中执行初始化。
这当然是个人喜好的问题。但是我要做什么取决于你要做的手术的长度。如果加载插件需要时间,我会创建一个公共方法,任何用户在使用类之前都需要调用该方法。另一种方法是将方法放在构造函数中,但是IMO构造函数应该尽可能快地返回,并且应该包含字段/属性初始化。
class PluginProvider
{
private bool _isInitialized;
IEnumerable<IPluginType> PluginTypes { get; set;}
public void Initialize()
{
if (_isInitialized)
{
return;
}
InitializePlugins();
_isInitialized = true;
}
}
注意,这样做的缺点是,您必须确保在使用任何操作之前调用Initialize方法。
支持这种方法的另一件事是异常处理。我确信您不会希望您的构造函数抛出任何类型的IOException
,以防它无法从文件系统加载类型。
任何初始化类型的代码都应该在构造函数中完成,这样你就知道它只会被调用一次。
public class PluginProvider
{
IEnumerable<IPluginType> PluginTypes
{
get
{
return _pluginTypes;
}
}
public PluginProvider()
{
InitializePlugins();
}
}
您在这里所做的称为延迟初始化。您正在推迟执行一个可能代价高昂的操作,直到需要其输出的时刻。
现在,这不是一个绝对的规则。如果你的InitializePlugins
方法需要很长时间才能完成,这可能会影响用户体验,那么你可以考虑将其移动到一个公共方法中,甚至使其异步,并在属性之外调用它:在应用程序启动时或当你找到一个合适的时刻调用一个持久的操作。
否则,如果它是一个短暂的一次性的东西,它可以留在那里。正如我所说,这不是绝对的规则。一般来说,这些都是一些适用于特定情况的指导原则。