这是一个有点奇怪的 oop 问题。我想创建一组对象(在设计时已知),每个对象都有与之关联的某些功能。 我可以通过为我的对象提供可以包含“代表”的属性来做到这一点:
public class StateTransition {
Func<bool> Condition { get; set; }
Action ActionToTake { get; set; }
Func<bool> VerifyActionWorked { get; set; }
}
StateTransition foo = new StateTransition {
Condition = () => {//...}
// etc
};
或者,我可以使用一个抽象类并为我想创建的每个对象实现它:
public abstract class StateTransition {
public abstract bool Condition();
public abstract void ActionToTake();
public abstract bool VerifyActionWorked();
}
class Foo : StateTransition {
public override bool Condition() {//...}
// etc
}
Foo f = new Foo();
我意识到这两种方法的实际结果(在设计时创建与运行时创建)完全不同。
如何选择适合我应用的方法?
最佳答案
第一种方法看起来比原始委托(delegate)更适合事件,但是......无论如何。
他们之间的关键因素是:谁控制发生的事情?
如果调用者可以在那里合法地做任何事情,那么事件方法就可以了。毕竟,系统不会强制您继承 Button
只是为了添加单击它时发生的事情(尽管您可以那样做)。
如果“可能发生的事情”得到很好的控制,并且您不希望每个调用者 做不同的事情,那么子类方法更合适。这也避免了每个调用者都需要必须告诉它做什么,而“要做的事情”实际上可能只有很少的几个选项。基类型方法还提供了控制子类的能力,例如,通过在基类上仅具有internal
构造函数(以便仅在同一程序集中键入,或在通过 [InternalsVisibleTo(...)]
注释的程序集中,可以将其子类化)。
您还可以通过以下方式将两者结合起来(覆盖与事件):
public class StateTransition {
public event Func<bool> Condition;
protected virtual bool OnCondition() {
var handler = Condition;
return handler == null ? false : handler();
}
public event Action ActionToTake;
protected virtual void OnActionToTake() {
var handler = ActionToTake;
if(handler != null) handler();
}
public event Func<bool> VerifyActionWorked;
protected virtual bool OnVerifyActionWorked() {
var handler = VerifyActionWorked;
return handler == null ? true : handler();
}
// TODO: think about default return values
}
委托(delegate)/事件方法要考虑的另一件事是:如果委托(delegate)为 null
,您会怎么做?如果您需要全部 3 个,那么在构造函数中要求全部 3 个是个好主意。
关于c# - 在 OOP 中覆盖方法与分配方法委托(delegate)/事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14253099/