4

A()C# を使用して、 functionが function の直前に呼び出された場合、追加の作業を行う必要がありますC()A()間に他の関数が呼び出された場合、C()その余分な作業はしたくありません。コードの重複を最小限にするアイデアはありますか?

flag = false;すべての関数にB1..のような行を追加しないようにしていますBN

以下は非常に基本的な例です。

bool flag = false;

void A()
{
    flag = true;
}

void B1()
{
    ...
}

void B2()
{
    ...
}

void C()
{
    if (flag) 
    {
        //do something
    }
}

上記の例は単純なケースを使用しただけですが、ブール値以外のものを使用することもできます。C()重要なことは、ある種のフラグを設定およびリセットして、それに応じて動作する方法を認識できるようにしたいということです。

ご協力ありがとうございました。明確化が必要な場合は、投稿を編集します。

4

4 に答える 4

7

「余分な作業」をメモ化された関数 (つまり、結果をキャッシュする関数) に分解しないのはなぜですか? その作業が必要なときはいつでもこの関数を呼び出すだけで、キャッシュが新鮮な場合は短絡します。その作業が古くなったときはいつでも、キャッシュを無効にします。上記のかなり奇妙な例では、各 B で関数呼び出しが必要であり、C で 1 つの関数呼び出しが必要になると思います。A を呼び出すと、キャッシュが無効になります。

あなたがその周りを探しているなら(つまり、すべての関数呼び出しをキャッチしてこの呼び出しを挿入する賢い方法)、私は本当に気にしません. 非常識なランタイム リフレクション プロキシ クラスの生成を思いつくこともできますが、コード フローを明確かつ明確にする必要があります。各関数が既に行われている作業に依存している場合は、それぞれで「doWork」を呼び出すだけです。

于 2010-04-12T23:07:07.660 に答える
3

あるメソッドを呼び出すと別のメソッドの動作が変わるため、正しい順序でそれらを呼び出す必要がある場合、設計があまりにも密接に結合されているように思えます。それは重大な危険信号です。

いくつかのリファクタリングが順調に進んでいるようです。実際のコードをもっと見ずにアドバイスをするのは少し難しいですが、ここに正しい方向へのポイントがあります。

次のように C にパラメーターを追加することを検討してください。

void C(bool DoExtraWork) {
  if (DoExtraWork)...
}

もちろん、「DoExtraWork」には、呼び出し元のコンテキストで意味のある名前を付ける必要があります。

于 2010-04-12T23:13:49.127 に答える
1

同様の状況 (つまり、A が C の直前に呼び出されたかどうかを知る必要性) の問題を、単純なステート マシンを配置することで解決しました。基本的に、列挙型とプロパティを使用して状態オブジェクトを作成し、状態を管理/クエリしました。

A() に相当するものが呼び出されると、A が呼び出されたことを示す状態からビジネス ロジック部分が保存されます。他のメソッド (あなたの B ) が呼び出された場合、状態を他のいくつかの状態のいずれかに切り替えます (私の状況はもう少し複雑でした)。次に C() が呼び出されると、ビジネス ロジックの部分がクエリされて、 「Aが呼び出された場合のみ」機能を保持するメソッドD()を呼び出す予定でした。

この問題を解決するには複数の方法があると思いますが、最初はバイナリの状況だったものを、より複雑なマルチステートの状況を処理するために拡張できるため、私が採用したステート マシンのアプローチが気に入りました。

私の場合、マルチスレッドが問題にならなかったのは幸運でした。なぜなら、それは物事をより面白くする傾向があるからですが、ステート マシンはそのシナリオでも機能する可能性があります。

ちょうど私の2セント。

于 2010-04-12T23:28:51.800 に答える
0

私はこれをお勧めしませんが、なんてこった: すべての単純なメソッド呼び出しを置き換えたい場合:

A();

...次のような構文で:

// _lastAction is a class-level Action member
(_lastAction = new Action(A)).Invoke();

...その後、C()あなたの中で次のようなチェックを行うことができます:

void C()
{
    if (_lastAction.Method.Name == "A")
    {

    }
}

これはおそらくスレッド セーフではありません (そして、難読化ツールを介して実行されるコードでは、少しいじくり回さないと機能しません)。また、この期間のようなものは使用しません。

注: 私の古いバージョンの C# にはAction<T>(ActionまたはAction<T, T>などではない) しかありません。そのため、このアプローチを使用するには、各メソッドにダミー パラメーターを追加する必要があります。

于 2010-04-13T00:36:07.960 に答える