在属性中执行初始化是一个好习惯吗?

时间:2014-08-11 05:21:09

标签: c# methods properties design-guidelines

我有一个类PluginProvider,它使用PluginLoader组件从文件系统加载插件(托管/本机)。在PluginProvider类中,当前定义了一个名为' PluginTypes'它调用了“InitializePlugins”' get()的实例方法。

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,发现了这个&#34;特别是,访问网络或文件系统的操作(不是一次初始化)应该很可能是方法,而不是属性。&#34;。现在我有点困惑。请帮忙。

4 个答案:

答案 0 :(得分:2)

  • 如果您想尽可能地延迟初始化,并且在 您的财产(或属性)时不知道,您正在做的事情很好
  • 如果您想延迟并且您可以控制第一次调用属性的时间,那么您可能希望公开您的方法InitializePlugins()并在访问该属性之前显式调用它。此选项还可以异步初始化。例如,您可以使用InitializePluginsAsync()返回Task
  • 如果延迟初始化不是一个大问题,那么只需在构造函数中执行初始化。

答案 1 :(得分:1)

任何初始化类型的代码都应该在构造函数中完成,这样你知道它只会被调用一次。

public class PluginProvider
{
   IEnumerable<IPluginType> PluginTypes
   {
      get
      {
        return _pluginTypes;
      }
   }

   public PluginProvider()
   {
      InitializePlugins();
   }
}

答案 2 :(得分:1)

这当然是品味问题。但我会做什么取决于你尝试执行的操作的长度。如果加载插件需要时间,我会创建一个公共方法,任何用户在使用该类之前都需要调用它。另一种方法是将方法放在构造函数中,但IMO构造函数应该尽快返回并且应该包含字段/属性初始化。

class PluginProvider
{
    private bool _isInitialized;
    IEnumerable<IPluginType> PluginTypes { get; set;}

    public void Initialize()
    {
        if (_isInitialized)
        {
             return;
        }      

        InitializePlugins();
        _isInitialized = true;  
    }
}

请注意,这方面的缺点是您必须确保在执行任何操作之前调用Initialize方法。

支持这种方法的另一件事是异常处理。我确定你不希望你的构造函数抛出任何类型IOException,以防它无法从文件系统加载类型。

答案 3 :(得分:1)

你在做什么叫做延迟初始化。你推迟进行可能代价高昂的操作,直到需要输出为止。

现在,这不是一个绝对的规则。如果您的InitializePlugins方法需要很长时间才能完成并且可能会影响用户体验,那么您可以考虑将其移动到公共方法中,甚至将其设置为异步并在属性之外调用它:在应用启动时或每当您找个好时机来做一个持久的操作。

否则,如果它是一个短暂的一次性事物,它可以留在那里。正如我所说,不是绝对的规则。通常,这些是适用于特定情况的一些指导原则。