如何强制执行基类中的代码并允许用户编写自己的代码实现?

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

How to force execution of a code in a base class and let the user also write his implementation of the code?

问题

以下是要翻译的代码部分:

我想创建一个抽象基类,其中包含一个Run()方法。每当这个类的任何子类需要运行时,我将调用这个run()方法。运行的实现必须在子类中,而不是在基类中,但我希望能够确保在运行后记录最后一次运行的时间和日期。

这是我的基类:

```csharp
public abstract class Monitor
{
    public void Run()
    { 
        LastRun = DateTime.Now;
    }

    public DateTime LastRun { get; private set; }
}

通常情况下,我的Run()方法必须是抽象的,以强制任何实现Monitor的用户编写运行体。但如果是抽象的,我就不能在基类中拥有方法体。有没有解决这个问题的模式?


<details>
<summary>英文:</summary>

I would like to create an abstract base class with a Run() method. Each time any child of this class need to run I will call this run() method. The implementation of the run must be in the child, not in the base class but I would like to be sure that I record the last run time and date after the run.

Here is my base class:

public abstract class Monitor
{
public void Run()
{
LastRun = DateTime.Now;
}

public DateTime LastRun { get; private set; }

}


Normally my method Run() must be abstract to force any user that implement Monitor to write the run body. But if abstract I cannot have a body in my base class. Is there  pattern for this?

</details>


# 答案1
**得分**: 6

public abstract class Monitor
{
public void Run()
{
RunImpl();
LastRun = DateTime.Now;
}

protected abstract void RunImpl();

public DateTime LastRun { get; private set; }

}


<details>
<summary>英文:</summary>

Example:

public abstract class Monitor
{
public void Run()
{
RunImpl();
LastRun = DateTime.Now;
}

protected abstract void RunImpl();

public DateTime LastRun { get; private set; }

}


</details>



# 答案2
**得分**: 1

也许你还可以重构以偏好 [组合而非继承](https://en.wikipedia.org/wiki/Composition_over_inheritance):

```csharp
public class Monitor
{
    private Action run;
    public DateTime? LastRun { get; private set; }

    public Monitor(Action run) => this.run = run;

    [MemberNotNull(nameof(LastRun))]
    public void Run()
    { 
        run();
        LastRun = DateTime.Now;
    }
}

// 客户端代码:
static void MyRun() {}
var m = new Monitor(MyRun);
m.Run();
Console.WriteLine(m.LastRun.Value);
英文:

Maybe you could also refactor to favor composition over inheritance:

public class Monitor
{
    private Action run;
    public DateTime? LastRun { get; private set; }

    public Monitor(Action run) =&gt; this.run = run;

    [MemberNotNull(nameof(LastRun))]
    public void Run()
    { 
        run();
        LastRun = DateTime.Now;
    }
}

// client code:
static void MyRun() {}
var m = new Monitor(MyRun);
m.Run();
Console.WriteLine(m.LastRun.Value);

huangapple
  • 本文由 发表于 2023年2月27日 19:28:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75579878.html
匿名

发表评论

匿名网友

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

确定