web-dev-qa-db-ja.com

ActionまたはFuncデリゲートでparamsを使用できますか?

アクションデリゲートでparamsを使用しようとすると...

private Action<string, params object[]> WriteToLogCallBack;

この設計時エラーを受け取りました:

クラス、構造体、またはインターフェイスメンバーの宣言に無効なトークン 'params'があります

助けて!

41
Homam

この回避策はどうですか?

private Action<string, object[]> writeToLogCallBack;
public void WriteToLogCallBack(string s, params object[] args)
{
  if(writeToLogCallBack!=null)
    writeToLogCallBack(s,args);
}

または、独自のデリゲートタイプを定義することもできます。

delegate void LogAction(string s, params object[] args);
42
CodesInChaos

C#では可変長型パラメーターは使用できません。

そのため、たとえば、Action<...>Func<...>Tuple<...>の宣言が多数あります。ただし、これは興味深い機能です。 C++ 0x ある

11
Jordão

あなたはこれを試すことができます。引数の数に制限はありません。引数の数やタイプを間違って渡すと、コンパイル時エラーが発生します。

public delegate T ParamsAction<T>(params object[] oArgs);

public static T LogAction<T>(string s, ParamsAction<T> oCallback)
{
    Log(s);
    T result = oCallback();
    return T;
}

Foo foo = LogAction<Foo>("Hello world.", aoArgs => GetFoo(1,"",'',1.1));
5
Bryan Clark

デリゲートの実際の宣言ではparamsを使用できますが、デリゲートのタイプでは使用できません。アクションへのジェネリックパラメータはタイプのみであり、デリゲートを呼び出すときに渡される実際の引数ではありません。 paramsはタイプではなく、キーワードです。

3

複数のメソッド呼び出しをラップする方法を示すために、ブライアンから上記のコードにマイナー拡張を行いました。
これを使用して、データベース呼び出しを含む複数のメソッドを1つのトランザクションにラップしています。
ありがとう、ブライアン:-)
(LINQPadで以下を実行してテストできます)

//Wrapper code
public delegate void MyAction(params object[] objArgs);
public static void RunActions(params MyAction[] actnArgs)
{
    Console.WriteLine("WrapperBefore: Begin transaction code\n");
    actnArgs.ToList().ForEach( actn =>  actn() );
    Console.WriteLine("\nWrapperAfter: Commit transaction code");
}

//Methods being called
public void Hash  (string s, int i, int j)  => Console.WriteLine("   Hash-method call: " + s + "###" + i.ToString() + j.ToString());
public void Slash (int i, string s)         => Console.WriteLine("   Slash-method call: " + i.ToString()+ @"////" + s);

//Actual calling code
void Main()
{  
  RunActions( objArgs => Hash("One", 2, 1)
             ,objArgs => Slash(3, "four")   );
}

//Resulting output: 
// 
//  WrapperBefore: Begin transaction code
//  
//  Hash-method call: One###21
//  Slash-method call: 3////four
//  
//  WrapperAfter: Commit transaction code  
1
kamgman