Question

I have this situation that when AbstractMethod method is invoked from ImplementClass I want to enforce that MustBeCalled method in the AbstractClass is invoked. I’ve never come across this situation before. Thank you!

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?
    }
}
Was it helpful?

Solution

An option would be to have the Abstract class do the calling in this manner. Otherwise, there is no way in c# to require an inherited class to implement a method in a certain way.

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

Doing this creates the desired public facing method in the abstract class, giving the abstract class over how and in what order things are called, while still allowing the concrete class to provide needed functionality.

OTHER TIPS

How about

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

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

Why can't you just call the method in the AbstractMethod() of Implement class?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top