How to enforce a method call (in the base class) when overriding method is invoked?

前端 未结 4 1307
不思量自难忘°
不思量自难忘° 2021-01-18 04:10

I have this situation that when AbstractMethod method is invoked from ImplementClass I want to enforce that MustBeCalled m

4条回答
  •  心在旅途
    2021-01-18 04:47

    One thing the preceding solutions ignore is that ImplementClass can redefine MethodToBeCalled and not call 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();
        }
    }
    

    If only C# allowed non-overridden methods to be sealed - like Java's final keyword!

    The only way I can think of to overcome this is to use delegation rather than inheritance, because classes can be defined as sealed. And I'm using a namespace and the "internal" access modifier to prevent providing a new implementation on implementing classes. Also, the method to override must be defined as protected, otherwise users could call it directly.

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

提交回复
热议问题