如何执行一个方法调用(基类)覆盖方法被调用时?(How to enforce a method ca

2019-06-26 04:04发布

我有这种情况,当AbstractMethod方法是从ImplementClass调用我要强制执行,在抽象类 MustBeCalled方法被调用。 我从来没有过这种情况之前。 谢谢!

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

Answer 1:

一种选择是将有抽象类做主叫这种方式。 否则,在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?
    }
}

这样做会在抽象类所需的面向公众的方法,从而在事情是如何以及以什么顺序叫抽象类,同时还允许具体类,以提供所需的功能。



Answer 2:

怎么样

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


Answer 3:

有一件事上述解决方案忽视的是,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的final关键字!

我能想到的解决这个唯一的方法是使用委托而不是继承,因为类可以作为密封定义。 而我使用的是命名空间和“内部”访问修饰符,防止提供关于实现类一个新的实现。 此外,要覆盖的方法必须被定义为保护,否则用户可以直接调用它。

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");
    }
}


Answer 4:

为什么你就不能调用在AbstractMethod()的实现类中的方法?



文章来源: How to enforce a method call (in the base class) when overriding method is invoked?