抽象类中的执行顺序

时间:2014-05-11 23:10:14

标签: c# inheritance abstract-class

我遇到了一个帖子,据说如果我们让Abstract类以这种方式进行调用,就会调用MustBeCalled()方法。

public abstract class AbstractClass
{
    public void PerformThisFunction()
    {
        MustBeCalled();
        AbstractMethod();
    }

    public void MustBeCalled()
    {
        //this must be called when AbstractMethod is invoked
    }

    //could also be public if desired
    protected abstract void AbstractMethod();
}

public class ImplementClass : AbstractClass
{
    protected override void AbstractMethod()
    {
        //when called, base.MustBeCalled() must be called.
        //how can i enforce this?
    }
}

但是如何调用MustBeCalled()方法? 这里叫什么顺序?

2 个答案:

答案 0 :(得分:3)

如果您先调用PerformFunction(),那么所有内容都将按照预期的顺序执行,其中该顺序是按PerformFunction()中的代码行顺序指定的。如果您直接致电AbstractMethod(),则无法保证MustBeCalled()将被调用。但是,我注意到您AbstractMethod()标记为protected,这意味着您班级的外部消费者将无法直接调用它。他们必须使用PerformFunction() - 这很好,因为现在只有一种公共方式来调用你的内部方法,这样就可以保证你需要的顺序。

事实上,只有通过选择编写代码才能确保事情发生,才能保证事情的发生。例如,你不能保证代码将实现俄罗斯方块游戏,除非实际编写代码并选择以产生俄罗斯方块行为的方式实现它。类型系统和public / protected / private修饰符可以通过防止一些滥用来帮助一些(因为你的内部不可访问,因此你的模块的消费者不能调用它),但它们只能到目前为止。就是这种情况。

答案 1 :(得分:0)

您无法强制实现在调用时调用方法的方式。实现可以完全自己做,也可以什么也不做。

public class ImplementClass : AbstractClass
{
    protected override void AbstractMethod()
    {
        // this is a perfectly valid implementation
    }
}    

更好的实施可能是。

public abstract class AbstractClass
{
    public void PerformThisFunction()
    {
        MustBeCalled();
        AbstractMethod();
    }

    private void MustBeCalled()
    {

    }

    protected virtual void AbstractMethod()
    {
        MustBeCalled();
    }
}

这种重构工具至少会创建所需的样板代码:

public class ImplementClass : AbstractClass
{
    protected override void AbstractMethod()
    {
        base.AbstractMethod();
    }
}   

但是,覆盖AbstractMethod的人仍然需要调用base.AbstractMethod,编译器根本不会执行此操作。