13

Dynamic-invokeで呼び出すことができる可変数のパラメータを取ることができるC#ラムダ/デリゲートを持つことは可能ですか?

このコンテキストで「params」キーワードを使用しようとする試みはすべて失敗しました。


回答からの作業コードで更新:

delegate void Foo(params string[] strings);

static void Main(string[] args)                       
{
    Foo x = strings =>
    {
        foreach(string s in strings)
            Console.WriteLine(s);
    };

    //Added to make it clear how this eventually is used :)
    Delegate d = x;

    d.DynamicInvoke(new[]{new string[]{"1", "2", "3"}});
}
4

5 に答える 5

15

引数を直接渡すときに機能しない理由DynamicInvoke()DynamicInvoke()、オブジェクトの配列、ターゲット メソッドのパラメーターごとに 1 つの要素が必要であり、コンパイラが単一の配列を単一の引数ではなくparams配列として解釈するためです。DynamicInvoke()ターゲットメソッドに(単一のとしてキャストしない限りobject)。

DynamicInvoke()ターゲット メソッドのパラメーター配列を含む配列を渡して呼び出すこともできます。外側の配列はDynamicInvoke()の単一のparamsパラメータの引数として受け入れられ、内側の配列はターゲット メソッドのparams配列として受け入れられます。

delegate void ParamsDelegate(params object[] args);

static void Main()
{  
   ParamsDelegate paramsDelegate = x => Console.WriteLine(x.Length);

   paramsDelegate(1,2,3); //output: "3"
   paramsDelegate();      //output: "0"

   paramsDelegate.DynamicInvoke((object) new object[]{1,2,3}); //output: "3"
   paramsDelegate.DynamicInvoke((object) new object[]{}); //output: "0"

   paramsDelegate.DynamicInvoke(new []{new object[]{1,2,3}}); //output: "3"
   paramsDelegate.DynamicInvoke(new []{new object[]{}});      //output: "0"
}
于 2010-08-27T03:31:44.447 に答える
1

いいえ。ただし、必要なパラメータはすべて配列にすることができます。

詳細がなければ、それは長短です。

于 2010-08-27T03:38:29.427 に答える
0

マークの答えに加えて、少しクリーンアップする拡張メソッドを作成します。

static DynamicInvokeParams(this ParamsDelegate delegate, params object[] args)
{
  delegate.DynamicInvoke(new [] {args});
}

そして、あなたはただ言う必要があります:

paramsDelegate.DyanamicInvokeParams(1, 2, 3);
于 2010-08-27T03:58:18.720 に答える
0

いいえ、しかし、少しの助けを借りて、ほとんど偽造することができます:

object[] Params(params object[] args) { return args;}

// :

Action<string, object[]> CWL = 
                  (format,  args) => Console.WriteLine(format, args);

CWL("{0}, {1}", Params(1,2));
于 2010-08-27T03:52:23.720 に答える
0

ここで議論されていない非常に重要な点があるように感じます。それは、引数を取るデリゲート型を定義した場合、それparamsを呼び出す意味はほとんどないというDynamicInvokeことです。これが機能する唯一のシナリオは、カスタム型のデリゲートがあり、Delegate引数を受け入れてそれを呼び出すメソッドDynamicInvokeにパラメーターとして渡す場合です

しかし、OPの更新でこのコードを見てみましょう:

delegate void Foo(params string[] strings);

static void Main(string[] args)                       
{
    Foo x = strings =>
    {
        foreach(string s in strings)
            Console.WriteLine(s);
    };

    x.DynamicInvoke(new[]{new string[]{"1", "2", "3"}});
}

上記のDynamicInvoke呼び出しはまったく不要です。その最後の行を読む方がはるかに賢明です:

x("1", "2", "3");
于 2010-08-27T04:08:55.100 に答える