1

さまざまなオブジェクトの1つでメソッドを実行したいのですが、メソッド呼び出しの前後に、さまざまなメンテナンスタスクを実行するための関数を実行する必要があります。前後に実行する関数は常に同じです。メソッドの戻り値のタイプとパラメーターは、ほとんど何でもかまいません。

現在、私が使用している可能性のあるすべてのメソッドシグネチャのデリゲートを定義することでこれを行っていますが、これを行うのは非常に厄介です。これは一例です:

protected delegate void DelVoidString(string string1);
protected void Execute(DelVoidString p, string string1)
{
    PreInvoke();
    p.Invoke(string1);
    PostInvoke();
}

署名を除いて、それらすべてのコードは同一です。だから私の質問は:これを行うためのより良い方法はありますか?デリゲートを必要とするメソッド呼び出しの前後にPreInvoke()とPostInvoke()を実行する手段がある限り、デリゲートを使用することに執着していません。そのコードを毎回書き出すことを忘れないでください。

私はラムダ式について漠然とした知識しか持っていません...彼らはここで私をよりよく助けることができますか?それとも私は他の途方もなく明白な何かを見逃していますか?ありがとう!

4

3 に答える 3

4

ジェネリックスと組み込みのSystem.Actionデリゲート型を使用して、重複の一部を減らすことができます。

protected void Execute(Action action)
{
    PreInvoke();
    action();
    PostInvoke();
}

protected void Execute<T>(Action<T> action, T arg)
{
    PreInvoke();
    action(arg);
    PostInvoke();
}

protected void Execute<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
{
    PreInvoke();
    action(arg1, arg2);
    PostInvoke();
}

// Additional methods for three arguments, four arguments, etc.

戻り値を処理するには、次を使用しますSystem.Func

protected TResult Execute<TResult>(Func<TResult> func)
{
    PreInvoke();
    TResult result = func();
    PostInvoke();
    return result;
}

protected TResult Execute<T, TResult>(Func<T, TResult> func, T arg)
{
    PreInvoke();
    TResult result = func(arg);
    PostInvoke();
    return result;
}

また、C#のアスペクト指向プログラミング(AOP)を調べることもできます。

于 2012-04-26T03:58:49.630 に答える
0

他の人が提供したテーマのバリエーションを提供する-あなたは一般的な抽象基本クラスを作り、それから次のように継承することを検討するかもしれません:

public abstract class Executable<T>
{
    protected void Execute(Action<T> action, T value)
    {
        PreInvoke();
        action();
        PostInvoke();
    }
    private void PreInvoke() { /* something */ }
    private void PostInvoke() { /* something */ }
}

public MyFooExecutable : Executable<string>
{
}

stringこの種の実装は、MyFooExecutableクラスのジェネリック型を閉じます。これにより、すべての種類のTに対して型を開いたままにすることなく、型を変更する他のサブクラスを作成できます。Pre / Post-Invokeメソッドの機能によっては、代わりにこれらを拡張メソッドに入れて、インターフェイスにコーディングすることで解決できる場合もあります。

public interface IInvocable
{
   void PreInvoke();
   void PostInvoke();
}

public class MyFooExecutable : IInvocable
{
    public void PreInvoke() { /* something */ }
    public void PostInvoke() { /* something */ }
}

public static class InvocableExtensions
{
    public static void Execute<T>(this IInvocable self, Action<T> action, T value)
    {
        self.PreInvoke();
        action(value);
        self.PostInvoke();
    }
}
于 2012-04-26T04:24:32.573 に答える
0

多くのメソッドでこの事前/事後呼び出しメカニズムが必要な場合は、PostSharpのような.net用のAOPツールの使用を検討する必要があると思います。

PostSharpのOnMethodBoundaryAspectの使用例は、DrorHelperブログまたはPostSharpサイトの例にあります。

于 2012-04-26T05:25:19.143 に答える