简体   繁体   English

C#Lambda中的变量参数

[英]Variable parameters in C# Lambda

Is it possible to have a C# lambda/delegate that can take a variable number of parameters that can be invoked with a Dynamic-invoke? 是否可以使用C#lambda / delegate来获取可以使用Dynamic-invoke调用的可变数量的参数?

All my attempts to use the 'params' keyword in this context have failed. 我在这种情况下使用'params'关键字的所有尝试都失败了。


UPDATE WITH WORKING CODE FROM ANSWER : 来自答案的工作代码更新:

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"}});
}

The reason that it doesn't work when passing the arguments directly to DynamicInvoke() is because DynamicInvoke() expects an array of objects, one element for each parameter of the target method, and the compiler will interpret a single array as the params array to DynamicInvoke() instead of a single argument to the target method (unless you cast it as a single object ). 将参数直接传递给DynamicInvoke()时它不起作用的原因是DynamicInvoke()需要一个对象数组,一个元素用于目标方法的每个参数,编译器会将一个数组解释为params数组到DynamicInvoke()而不是目标方法的单个参数(除非将其转换为单个object )。

You can also call DynamicInvoke() by passing an array that contains the target method's parameters array. 您还可以通过传递包含目标方法的parameters数组的数组来调用DynamicInvoke() The outer array will be accepted as the argument for DynamicInvoke() 's single params parameter and the inner array will be accepted as the params array for the target method. 外部数组将被接受为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"
}

No, but any of the parameters it does take can be an array. 不,但它确实采取的任何参数都可以是一个数组。

Without more details, that's the long and short of it. 没有更多细节,这就是它的长短。

No, but with a little help, you can almost fake it: 不,但有一点帮助,你几乎可以伪造它:

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

// :

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

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

Adding to Mark's answer, I'd create an extension method to clean up a bit: 添加到Mark的答案,我将创建一个扩展方法来清理一下:

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

And then you just have to say: 然后你只需要说:

paramsDelegate.DyanamicInvokeParams(1, 2, 3);

I feel like there's a very crucial point that isn't being discussed here, and that's that if you've defined a delegate type that takes a params argument, there's very little point to calling DynamicInvoke on it at all . 我觉得有一个非常重要的一点,这里没有讨论,那就是如果你已经定义了一个带有params参数的委托类型,那么根本就没有必要调用DynamicInvoke The only scenario I can imagine in which this would come into play is if you have a delegate of your custom type and you are passing it as a parameter to some method that accepts a Delegate argument and calls DynamicInvoke on that . 我可以想象的唯一场景是,如果您有自定义类型的委托,并且将它作为参数传递给接受Delegate参数并在上调用DynamicInvoke某个方法。

But let's look at this code in the OP's update: 但是让我们看一下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"}});
}

The DynamicInvoke call above is totally superfluous. 上面的DynamicInvoke调用完全是多余的。 It would be much more sensible for that last line to read: 最后一行阅读更为明智:

x("1", "2", "3");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM