init方法只调用一次c#

时间:2013-10-04 17:56:59

标签: c# init

嗯,我知道这已经被问到了,我也碰巧知道最简单的方法。

现在我的问题更多的是关于你是否有更好的方法的建议。

我希望在启用或创建组件时只调用一次我的方法。 请参阅我可以创建一个组件但是禁用它,然后当我第一次启用它时,我希望调用Init方法。该组件包含在“附加”对象中。

所以我有

的组件
internal bool _runOnce;

然后我有了MainObject

List<Component> _listComp = new List<Component>();
void Update(){
   foreach(Component c in _listComp){
      if(!c.enable)continue;
      if(c._runOnce){
          c.Init();
          c._runOnce = false;
      }
      c.Update();
   }
}

我主要担心的是,每个对象的每个组件都会检查_runOnce。我知道这只是一个布尔检查而且没有任何价值,但我只是想问是否有人会知道这个目的的模式比这更好。

由于

4 个答案:

答案 0 :(得分:2)

您还可以仅列出已启用的组件....

List<Component> _listEnabled = _listComp.Where(item => (item.enable == true));

foreach(Component c in _listEnabled ){
   if(c._runOnce){
      c.Init();           // if at all possible, _runOnce should be set to false
      c._runOnce = false; // IN THE OBJECT, after calling Init();
   }
   c.Update();
}

答案 1 :(得分:1)

我会质疑Update()是否是Init()动态组件的合适生命周期设计。

似乎有一个名义上称为GameObject.ActivateComponent(AbstractComponent C)调用C.Init()AbstractComponent::Init调用OnInit的方法更有意义,这是组件覆盖和实现的内容。 AbstractComponent::Init将进行_runonce检查并提前返回。这是一个方法调用,但它使代码更抽象,并且可以选择扩展为稍后有OnReinitialize代码路径,如果你需要为'这是第二次或以后我是init'提供钩子d”。 (比方说,统计重置选项...)

Update()探测像“runonce”这样的实现细节以了解Component的初始化状态肯定是错误的。

List<Component> _listComp = new List<Component>();
void Update(){
   foreach(Component c in _listComp){
  c.Update();
   }
}

AbstractComponent

 public bool Enable { get;set;}
 private bool _initialized = false;

 void Update(){
     if (!Enable) return;
     Init();
     OnUpdate();
 }

 protected virtual void OnUpdate()
 {
 // filled in by user script
 }

 private void Init()
 {
 if (_initialized) return;
 OnInit();
 _initialized = true;
 }

 protected virtual void OnInit()
 {
 // filled in by user script
 }

答案 2 :(得分:1)

My main concern is that the check for _runOnce will happen every frame for every component on each object.

由此我假设您经常致电Update。我担心的是组件的Update方法,它很可能比布尔检查贵得多。这称为微优化:你付出了很多努力,而不是一个根本不存在问题的东西。

但是,我建议封装初始化。您的MainObject无需知道任何相关信息。 _runOnce应该是组件的私有成员,enable应该是属性(btw:_runOnce应该在某处初始化为true)。每次启用组件时,您都可以检查_runOnce并在需要时调用初始化:

public class MyComponent
{
    private bool _isInitialized; // I think this is a better name than _runOnce
    private bool _enable;

    public bool Enable
    {
        get
        {
            return _enable;
        }
        set
        {
            if (_enable == value)
            {
                return;
            }

            if (value == true && !_isInitialized)
            {
                Init();
            }

            _enable = value;
        }
    }

    private void Init()
    {
        // initialization logic here ...

        _isInitialized = true;
    }
}

另一个想法是将初始化推迟到Update方法。这基本上是你已经拥有的,但在面向对象的设计中:

public void Update()
{
    if (_enable && !_isInitialized)
    {
        Init();
    }

    // update logic here ...
}

答案 3 :(得分:0)

如果只是Component的常规构造函数?

public Component()
{
   Init();
}