英文:
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) => 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);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论