8

同じパターンでいくつかのロギングを必要とする多くのメソッドがあります。値を返す必要があるメソッドもあれば、返さないメソッドもあります。すべてのロジックのコピーペーストを避けるために、Action パラメーターを使用してメソッドを作成しました。次のようになります。

private void Execute(Action action)
{
   Logger.Start();
   try
   {
      action();
   }
   catch(Exception exception)
   {
      Logger.WriteException();
      throw;
   }
   finally
   {
       Logger.Finish();
   }
}

今、そのような電話がいくつかあります

public void DoSomething(string parameter)
{
    Execute(() => GetProvider(parameter).DoSomething());
}

しかし、値を返す関数が必要です。それを行う最良の方法は何ですか?私は今2つ見つけました:

1) Func で Execute メソッドのコピーを作成する

private T Execute<T>(Func<T> action)
{
   Logger.Start();
   try
   {
      return action();
   }
   catch(Exception exception)
   {
      Logger.WriteException();
      throw;
   }
   finally
   {
       Logger.Finish();
   }
}

この方法は機能しますが、コピーペーストもあります。

2) パラメータをだましてアクションにします。

public Result DoSomething(string parameter)
{
    Result result = null;
    Execute(() => result = GetProvider(parameter).DoSomething());
    return result;
}

これはコピーペーストを必要としませんが、見栄えがよくありません。

これらの方法のいずれかを回避するために何らかの形で Action と Func を結合する方法はありますか、または同じ結果を達成する別の方法があるかもしれませんか?

4

3 に答える 3

7

3 番目のオプションは、引き続き をオーバーロードすることですが、バージョンに関してはバージョンが機能Executeするようにします。ActionFunc

private void Execute(Action action)
{
    // We just ignore the return value here
    Execute(() => { 
        action();
        return 0; 
    });
}

もちろん、これはすべてvoid「実際の」型 ( UnitF# などの場合のように)に似ていれば、より単純Task<T>TaskなりTask<T>ます。

于 2013-04-02T13:36:44.930 に答える
3

Executeを に変換Funcするのコピーを作成しますActionExecuteその醜いコードを 1 回書くだけで、メソッドの完全な 2 番目のコピーが作成されるわけではありません。

private T Execute<T>(Func<T> func)
{
    T result = default(T);
    this.Execute(() => { result = func(); });
    return result;
}

...

public Result DoSomething(string parameter)
{
    return Execute(() => GetProvider(parameter).DoSomething());
}
于 2013-04-02T13:40:21.517 に答える