0

これは単純化されたセットアップです。私は API を持っています (API を制御することはできません)。これは、次のような Func プロパティを公開します。

public Func<dynamic, MyClass> FuncProperty { get; set; }

通常は次のように使用します。

api.FuncProperty = s =>
   {
      do1();
      do2();
      return new MyClass(); //simplified
   }

同様のコードがいたるところで使用されています (もちろん、{} の内容は異なります)。これらすべてに共通の機能を追加したいので、次のように使用できる「ラッパー」メソッドを作成したいと思います。

api.FuncProperty = MyWrapperMethod( 
   s =>
   {
      do1();
      do2();
      return new MyClass();
   });

これらすべての呼び出しを次のように編集できることを知っています。

api.FuncProperty = s =>
  {
     DoMyCommonFunctionality();
     //... as before
  }

しかし、私の一般的な機能が次のようなものである場合:

using(var disposable = SetSomeState())
{
   //the stuff which previously was in the lambda
}

次に、後者のアプローチを使用するのはちょっと見苦しいです。

そのため、たとえそれが学習目的であっても、ラッパーのメソッド シグネチャはどのように見えるべきなのでしょうか? また、どのように使用すればよいですか?

4

3 に答える 3

2

私があなたを正しく理解していればFunc<dynamic, MyClass>、次のように も返されるはずです:

public static Func<dynamic, MyClass> MyWrapperMethod(Func<dynamic, MyClass> func)
{
    // Validation if you want
    return d =>
    {
        using(var disposable = SetSomeState())
        {
            return func(d);
        }
    };
}

usingそれはあなたが望んでいたステートメントの例です。

呼び出しは、渡したデリゲートを呼び出さMyWrapperMethodないことに注意してください。代わりに、呼び出されたときに渡されたデリゲートを呼び出すデリゲートを返します。この種の遅延実行は混乱を招く可能性がありますが、ここで必要なことだと思います。

于 2011-08-23T21:18:24.720 に答える
1

次のようなことができます。

public Func<dynamic, MyClass> MyWrapperMethod(Func<dynamic, MyClass> func)
{
    if (func == null)
        throw new ArgumentNullException("func");

    return s => {
        DoMyCommonFunctionality();

        // Execute original function
        return func(s);
    };
}

メソッドをシミュレートするためにデリゲート プロパティを使用しているように見えることに注意してください。これは私にとって非常に悪いアーキテクチャのようなにおいがします。

于 2011-08-23T21:17:48.207 に答える
0

これを行うには複数の方法があります。

提案1

デリゲートに別の署名を作成する:

 public Func<HelperObject<dynamic>, MyClass> FuncProperty { get; set; }

次に、メソッドは次のように変更されます。

 api.FuncProperty = h =>
    {
        //h.Model is the dynamic
        //h.CommonHelperFunction()
        return new MyClass();
    };

そして、そのように呼び出します:

 api.FuncProperty(new HelperObject(someDynamic));

提案2

動的に拡張メソッドを作成して、必要なデータを提供します。

public static MyHelperClass CreateHelper(this object obj)
{
     return new MyHelperClass();
}

そして、あなたはそれを次のように使うことができます:

api.FuncProperty = s =>
  {
      var helper = (s as object).CreateHelper();

      return new MyClass();
  };

提案3

オブジェクトからプロパティとしてデリゲートを削除し、メソッドの抽象化に変更します。

 public MyClass ExecuteFunc(Func<dynamic, MyClass> selector)
 {
      Func<MyClass> helper = () =>
         {
             DoCommonFunctionality();
             return selector(x.Model);
         };

      return helper();
 }

次に、次のように呼び出します。

 api.ExecuteFunc(x => 
    {
        return new MyClass();
    });
于 2011-08-23T21:25:08.080 に答える