C# - 按继承顺序调用派生 类 中的重写方法
C# - Calling overridden methods in derived classes in order of inheritance
我希望能够按照派生的顺序调用重写的方法。
例如,在下面的代码中,我创建了一个名为 CallMeThird 的新 class,当调用它的 CallMe
方法时,我希望它执行基础 classes CallMe
继承顺序的方法:
- CallMeFirst
- CallMeSecond
- CallMeThird
不过有几件事我想避免:
- 在派生的 class 中调用
base.CallMe
OnCallMeFirst
和 OnCallMeSecond
作为 CallMe
的使用仍然暴露给派生的 classes,代码可能会变得混乱。
有没有漂亮、干净的模式可以用于这种情况?
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Base b = new CallMeThird();
b.CallMe();
while (Console.ReadKey().Key != ConsoleKey.Escape)
{
}
}
}
public abstract class Base
{
public abstract void CallMe();
}
public class CallMeFirst : Base
{
public override void CallMe()
{
Console.WriteLine("I would like to be called first");
}
}
public class CallMeSecond : CallMeFirst
{
public override void CallMe()
{
Console.WriteLine("I would like to be called second");
}
}
public class CallMeThird : CallMeSecond
{
public override void CallMe()
{
Console.WriteLine("I would like to be called third");
}
}
}
将 base.CallMe();
添加到每个覆盖,这样它将链接您的继承层次结构。
您可以随心所欲地避免它,但这是解决方案。覆盖意味着替换,如果你想使用父类实现,你最好调用它。
不过,我看不出这里有继承的必要。如果 CallMeThird 只是使用 CallMeSecond(等等)而不需要与其互换,I would prefer composition。这意味着 CallMeThird 将包含 CallMeSecond 和 return 对其 CallMe 方法的调用。然而,这个例子是精简的,以了解您的问题是组合问题还是继承问题。
正如 Nathan 指出的那样,存在通过 base
调用的能力来专门执行此操作,这可能是实现您想要的目标的最简单、最干净、性能最好和最稳定的方法。因此,我不建议 avoiding the feature that exists specifically to solve your problem,除非您有要求。
但是,如果您绝对确定要出于任何原因避免这种情况,这里有一个可能的替代方案:
- 避免多态性(使这些方法成为非虚方法)。
- 定义自定义属性。
- 用该属性修饰每个 class 中的所需方法。
- 在基 class 中的方法中,使用反射构建继承链(从基 class 直到对象的实际 class)。
- 对于链中的每个类型,select 用您的属性修饰的方法。
- 对于生成的方法序列,按您想要的顺序调用每个方法。
考虑Template Method避免使用多重继承。
我希望能够按照派生的顺序调用重写的方法。
例如,在下面的代码中,我创建了一个名为 CallMeThird 的新 class,当调用它的 CallMe
方法时,我希望它执行基础 classes CallMe
继承顺序的方法:
- CallMeFirst
- CallMeSecond
- CallMeThird
不过有几件事我想避免:
- 在派生的 class 中调用
base.CallMe
OnCallMeFirst
和OnCallMeSecond
作为CallMe
的使用仍然暴露给派生的 classes,代码可能会变得混乱。
有没有漂亮、干净的模式可以用于这种情况?
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Base b = new CallMeThird();
b.CallMe();
while (Console.ReadKey().Key != ConsoleKey.Escape)
{
}
}
}
public abstract class Base
{
public abstract void CallMe();
}
public class CallMeFirst : Base
{
public override void CallMe()
{
Console.WriteLine("I would like to be called first");
}
}
public class CallMeSecond : CallMeFirst
{
public override void CallMe()
{
Console.WriteLine("I would like to be called second");
}
}
public class CallMeThird : CallMeSecond
{
public override void CallMe()
{
Console.WriteLine("I would like to be called third");
}
}
}
将 base.CallMe();
添加到每个覆盖,这样它将链接您的继承层次结构。
您可以随心所欲地避免它,但这是解决方案。覆盖意味着替换,如果你想使用父类实现,你最好调用它。
不过,我看不出这里有继承的必要。如果 CallMeThird 只是使用 CallMeSecond(等等)而不需要与其互换,I would prefer composition。这意味着 CallMeThird 将包含 CallMeSecond 和 return 对其 CallMe 方法的调用。然而,这个例子是精简的,以了解您的问题是组合问题还是继承问题。
正如 Nathan 指出的那样,存在通过 base
调用的能力来专门执行此操作,这可能是实现您想要的目标的最简单、最干净、性能最好和最稳定的方法。因此,我不建议 avoiding the feature that exists specifically to solve your problem,除非您有要求。
但是,如果您绝对确定要出于任何原因避免这种情况,这里有一个可能的替代方案:
- 避免多态性(使这些方法成为非虚方法)。
- 定义自定义属性。
- 用该属性修饰每个 class 中的所需方法。
- 在基 class 中的方法中,使用反射构建继承链(从基 class 直到对象的实际 class)。
- 对于链中的每个类型,select 用您的属性修饰的方法。
- 对于生成的方法序列,按您想要的顺序调用每个方法。
考虑Template Method避免使用多重继承。