簡體   English   中英

C#Lambda中的變量參數

[英]Variable parameters in C# Lambda

是否可以使用C#lambda / delegate來獲取可以使用Dynamic-invoke調用的可變數量的參數?

我在這種情況下使用'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"}});
}

將參數直接傳遞給DynamicInvoke()時它不起作用的原因是DynamicInvoke()需要一個對象數組,一個元素用於目標方法的每個參數,編譯器會將一個數組解釋為params數組到DynamicInvoke()而不是目標方法的單個參數(除非將其轉換為單個object )。

您還可以通過傳遞包含目標方法的parameters數組的數組來調用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"
}

不,但它確實采取的任何參數都可以是一個數組。

沒有更多細節,這就是它的長短。

不,但有一點幫助,你幾乎可以偽造它:

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

// :

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

CWL("{0}, {1}", Params(1,2));

添加到Mark的答案,我將創建一個擴展方法來清理一下:

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

然后你只需要說:

paramsDelegate.DyanamicInvokeParams(1, 2, 3);

我覺得有一個非常重要的一點,這里沒有討論,那就是如果你已經定義了一個帶有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");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM