调用重写方法时如何强制执行方法调用(在基类中)?

时间:2009-07-17 01:37:59

标签: c# inheritance override method-call

我遇到这种情况,当从 ImplementClass 调用 AbstractMethod 方法时,我想在 AbstractClass <中强制执行 MustBeCalled 方法/ strong>被调用。我以前从未遇到过这种情况。谢谢!

public abstract class AbstractClass
{
    public abstract void AbstractMethod();

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

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

4 个答案:

答案 0 :(得分:8)

一个选项是让Abstract类以这种方式进行调用。否则,c#中没有办法要求继承的类以某种方式实现方法。

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?
    }
}

这样做会在抽象类中创建所需的面向公众的方法,为抽象类提供调用事物的方式和顺序,同时仍允许具体类提供所需的功能。

答案 1 :(得分:6)

怎么样

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

    protected abstract void InternalAbstractMethod();

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

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

答案 2 :(得分:0)

前面的解决方案忽略的一点是,ImplementClass可以重新定义MethodToBeCalled而不是调用MustBeCalled -

public abstract class AbstractClass
{
    public abstract void AbstractMethod();

    private void MustBeCalled()
    {
        //will be invoked by  MethodToBeCalled();
        Console.WriteLine("AbstractClass.MustBeCalled");
    }

    public void MethodToBeCalled()
    {
        MustBeCalled();
        AbstractMethod();
    }
}

public class ImplementClass : AbstractClass
{
    public override void AbstractMethod()
    {
        Console.WriteLine("ImplementClass.InternalAbstractMethod");
    }

    public new void MethodToBeCalled() {
        AbstractMethod();
    }
}

如果只有C#允许密封非覆盖方法 - 就像Java的最终关键字一样!

我能想到克服这一点的唯一方法是使用委托而不是继承,因为类可以被定义为密封。我正在使用命名空间和“内部”访问修饰符来阻止在实现类时提供新的实现。此外,覆盖方法必须定义为protected,否则用户可以直接调用它。

namespace Something
{

    public sealed class OuterClass
    {
        private AbstractInnerClass inner;

        public OuterClass(AbstractInnerClass inner)
        {
            this.inner = inner;
        }

        public void MethodToBeCalled()
        {
            MustBeCalled();
            inner.CalledByOuter();
        }

        public void MustBeCalled()
        {
            //this must be called when AbstractMethod is invoked
            System.Console.WriteLine("OuterClass.MustBeCalled");
        }
    }

    public abstract class AbstractInnerClass
    {
        internal void CalledByOuter()
        {
            AbstractMethod();
        }

        protected abstract void AbstractMethod();
    }
}

public class ImplementInnerClass : Something.AbstractInnerClass
{
    protected override void AbstractMethod()
    {
        //when called, base.MustBeCalled() must be called.
        //how can i enforce this?
        System.Console.WriteLine("ImplementInnerClass.AbstractMethod");
    }

    public new void CalledByOuter()
    {
        System.Console.WriteLine("doesn't work");
    }
}

答案 3 :(得分:-1)

为什么不能只调用Implement类的AbstractMethod()中的方法?