3

私は現在、Pythonデコレータのように機能するコードを持っています。関数を引数として取り、別の関数でラップされた同じ関数を返します(この場合、perforce接続を開いたり閉じたりします)。

    public Func<TArg, TReturn> EnableP4<TReturn, TArgs>(Func<TArg, TReturn> function)
    {
        Func<TArg, TReturn> p4Wrapper = (TArg funcArg) =>
        {
            try
            {
                if (con.Status.Equals(ConnectionStatus.Disconnected)) { con.Connect(options); }
                return function(funcArg);
            }
            finally { con.Disconnect(); }
        };
        return p4Wrapper;
    }

現時点では、これは 1 つの引数を持つ関数に対してのみ機能し、より一般的にできるかどうか疑問に思っていました (配列をメソッドにアンパックする方法があるかどうか)。

(これに沿​​った何か?)

    public Func<TArgs, TReturn> EnableP4<TReturn, TArgs>(Func<TArgs, TReturn> function)
    {
        Func<TArgs, TReturn> p4Wrapper = (TArgs args) =>
        {
            try
            {
                if (con.Status.Equals(ConnectionStatus.Disconnected)) { con.Connect(options); }
                return function(*args);
            }
            finally { con.Disconnect(); }
        };
        return p4Wrapper;
    }

TArgs は TArg[] です。

4

4 に答える 4

6

Func<T>(not ) を使用するだけFunc<TArg,TResult>で、コンパイラーがラムダ式のクロージャーを介して複数の引数を処理できるようになります。

メソッドを次のように変更した場合:

public Func<T> EnableP4<T>(Func<T> function)

次の方法でいつでも呼び出すことができます。

var newFunc = EnableP4(() => SomeFunc(arg1, arg2, arg3));

これは、複数のオーバーロードを持たずに任意の数の引数を許可するという点で優れています。

于 2013-08-21T17:00:28.690 に答える
1

いいえ、厳密に型指定された結果を使用して、C# で正確にこれを行うことができます。これは主に戻り値の型によるものです。任意の数のパラメーター (つまり、Emit またはリフレクション) を使用して関数の呼び出しを比較的簡単に構築できますが、厳密に型指定された結果を得るには、複数の関数が必要になります。

通常のアプローチでは、0 ~ n (多くの場合 0 ~ 3 で十分) の数の引数ごとに複数の関数を使用します。

public Func<TReturn> EnableP4<TReturn>(Func<T1, TReturn> function)...
public Func<T1, TReturn> EnableP4<TReturn, T1>(Func<T1, TReturn> function)....
public Func<T1, T2, TReturn> 
        EnableP4<TReturn, T1, T2>(Func<T1, T2, TReturn> function)...

ノート:

  • dynamicあなたが望むものに近づくかどうかを試すことができます
  • また、依存性注入フレームワーク (Unity など) を使用すると、すべてのメソッドをインターフェイス/クラスにラップできるため、場合によっては機能する可能性があります (データ アクセス レイヤー内のコードの何らかのリファクタリングのように見えるため、おそらくこのケースでは機能しません)。 )。
于 2013-08-21T17:00:16.993 に答える