使用计时器已过的方式防止子类中重复的代码

huangapple go评论52阅读模式
英文:

Prevent duplicating code in subclass using Timer Elapsed

问题

I have a base class which performs a Timer Elapsed call. Subclasses of this class also perform a Timer Elapsed call after the base class has finished. The base class sets a protected boolean which the subclass uses to determine if it needs to continue. See code below.

    protected virtual async void OnTimerElapsed(object sender, ElapsedEventArgs e)
    {
      if (someCondition) {
          isValid = false;
      }
      else {
          isValid = true;
      }

      if (!isValid)
      {
         return;
      }
    }
    protected override async void OnTimerElapsed(object sender, ElapsedEventArgs e)
    {
      base.OnTimerElapsed(sender, e);

      if (!isValid)
      {
        return;
      }
    }

I want to somehow eliminate the need for the if statement in the override function in the subclass, but I suspect there is no clean way to do this.

Does this appear to be the best way of doing this?

I've tried thinking about different ways of writing this, but because the Timer.Elapsed function is natively void, I couldn't think of other ways...

英文:

I have a base class which performs a Timer Elapsed call. Subclasses of this class also perform a Timer Elapsed call after the base class has finished. The base class sets a protected boolean which the subclass uses to determine if it needs to continue. See code below.

    protected virtual async void OnTimerElapsed(object sender, ElapsedEventArgs e)
    {
      if (someCondition) {
          isValid = false;
      }
      else {
          isValid = true;
      }

      if (!isValid)
      {
         return;
      }
    }
    protected override async void OnTimerElapsed(object sender, ElapsedEventArgs e)
    {
      base.OnTimerElapsed(sender, e);

      if (!isValid)
      {
        return;
      }
    }

I want to somehow eliminate the need for the if statement in the override function in the subclass, but I suspect there is no clean way to do this.

Does this appear to be the best way of doing this?

I've tried thinking about different ways of writing this, but because the Timer.Elapsed function is natively void, I couldn't think of other ways...

答案1

得分: 3

You can make OnTimerElapsed private and make the subsequent processing virtual.

public class BaseClass
{
    private bool _isValid;

    private bool Validate() { ... }

    private void OnTimerElapsed(object sender, ElapsedEventArgs e)
    {
        _isValid = Validate();
        if (!_isValid)
        {
            return;
        }

        DoProcessingWhenValid();
    }

    protected virtual void DoProcessingWhenValid() { ... }
}

public class DerivedClass : BaseClass
{
    protected override void DoProcessingWhenValid();
    {
        base.DoProcessingWhenValid();
        // More work here.
    }
}

请注意,从技术上讲,在这种简单的情况下,您甚至不需要_isValid,但仍然保留该字段可能是有道理的,也可能将其保护起来(或者protected { get; private set; },如果您想要更复杂的设置)。
这样做的最终结果是,在基类中只检查一次_isValid。所有派生类都可以假定DoProcessingWhenValid仅在_isValid为true时才被调用。如果需要,您可以将senderElapsedEventArgs传递给DoProcessingWhenValid,如果处理需要其中的某些信息。

英文:

You can make OnTimerElapsed private and make the subsequent processing virtual.
Example code (I ignore async for simplicity):

public class BaseClass
{
    private bool _isValid;

    private bool Validate() { ... }

    private void OnTimerElapsed(object sender, ElapsedEventArgs e)
    {
        _isValid = Validate();
        if (!_isValid)
        {
            return;
        }

        DoProcessingWhenValid();
    }

    protected virtual void DoProcessingWhenValid() { ... }
}

public class DerivedClass : BaseClass
{
    protected override void DoProcessingWhenValid();
    {
        base.DoProcessingWhenValid();
        // More work here.
    }
}

Note that technically you don't even need _isValid in this simple scenario, but it might make sense to still have the field, and potentially for it to remain protected (or even protected { get; private set; } if you want to get fancy).

The net result of this is that you only check _isValid once, in the base class. All derived classes can assume that DoProcessingWhenValid is only called when _isValid is true. If desired, you can pass the sender and ElapsedEventArgs into DoProcessingWhenValid, if the processing needs some of the information.

huangapple
  • 本文由 发表于 2023年4月4日 07:53:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75924526.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定