23

どういうわけか、派生クラスに常にオーバーライドされたメソッドベースを呼び出すように強制できますか?

public class BaseClass
{
    public virtual void Update()
    {
        if(condition)
        {
            throw new Exception("..."); // Prevent derived method to be called
        }
    }
}

そして、派生クラスで:

public override void Update()
{
    base.Update(); // Forced call

    // Do any work
}

非仮想Update()だけでなく、保護された仮想UpdateEx()を使用するための提案を検索して見つけました。あまりきれいに感じられないだけですが、もっと良い方法はありませんか?

質問があればいいのですが、英語が下手でごめんなさい。

4

4 に答える 4

32

テンプレートメソッドパターンを使用します-何らかの作業を行う必要のある基本メソッドをオーバーライドしないでください。特定のビットをオーバーライドします。これは、基本クラスで抽象またはno-opのいずれかになります。(通常、それをノーオペレーションにするか抽象クラスにするかの決定はかなり明白です-基本クラスは、具体的なクラスとして、それ自体で意味がありますか?)

これは基本的にあなたが見つけたパターンのように聞こえますUpdateEx-それは通常UpdateImplまたは私の経験では似たようなものですが。私の見解では、これはパターンとしては何も問題はありません。すべての派生クラスに同じコードを記述させて基本メソッドを呼び出すという考えを回避します。

于 2010-05-31T17:49:13.093 に答える
4

これにより、UpdateとUpdateExがどのようになるかを取得するのに少し時間がかかりました。これは他の人を助けるかもしれないコード例です。

public class BaseClass
{
    // This is the Update that class instances will use, it's never overridden by a subclass
    public void Update()
    {
        if(condition);
        // etc... base class code that will always run

        UpdateEx(); // ensure subclass Update() functionality is run
    }

    protected virtual void UpdateEx()
    {
        // does nothing unless sub-class overrides
    }
}

サブクラスには、Update()の実装はありません。UpdateEx()を使用してUpdate()に実装を追加します。

public class ConcreteClass : BaseClass
{
    protected override void UpdateEx()
    {
        // implementation to be added to the BaseClass Update();
    }
}

ConcreteClassのインスタンスは、Update()のBaseClass実装を一緒に使用しますが、ConcreteClassはUpdateEx()でそれを拡張します。

于 2015-05-08T20:16:49.263 に答える
2

あなたが見つけた提案は良いと思います。

基本クラスコンストラクターのサブクラスからの呼び出しを避けられない唯一の基本クラスメソッド。

于 2010-05-31T17:48:43.593 に答える
2

この種の問題の最も一般的な解決策は、拡張可能な仮想「フック」を呼び出す非仮想ベースメンバーを持つことだと思います。

ユースケースによっては、event代わりに使用することもできますが、イベントを実装するための通常のパターンはOnEvent、イベントハンドラーを追加する代わりに、サブクラスがオーバーライドできる仮想メソッドを使用することです。したがって、この例の場合、同じになります。もの。

于 2010-05-31T17:49:04.487 に答える