7

私は、 ImplementClassからAbstractMethodメソッドが呼び出されたときに、 AbstractClassの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?
    }
}
4

4 に答える 4

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

これを行うと、抽象クラスに目的の公開メソッドが作成され、具体的なクラスが必要な機能を提供できるようにしながら、どのように、どのような順序で呼び出されるかを抽象クラスに与えることができます。

于 2009-07-17T01:43:09.390 に答える
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?
    }
}
于 2009-07-17T01:42:31.700 に答える
0

上記のソリューションが無視していることの 1 つは、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();
    }
}

Java の final キーワードのように、オーバーライドされていないメソッドを封印できるのが C# だけだったら!

これを克服するために考えられる唯一の方法は、継承ではなく委譲を使用することです。これは、クラスをシールとして定義できるためです。また、名前空間と「内部」アクセス修飾子を使用して、実装クラスに新しい実装を提供しないようにしています。また、オーバーライドするメソッドは保護されているものとして定義する必要があります。そうしないと、ユーザーが直接呼び出すことができます。

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");
    }
}
于 2009-07-17T02:47:56.643 に答える
-1

Implement クラスの AbstractMethod() でメソッドを呼び出せないのはなぜですか?

于 2009-07-17T01:42:06.020 に答える