Переменные параметры в C # Lambda

Возможно ли иметь C # лямбда / делегат, который может принимать переменное число параметров, которые могут быть вызваны с помощью 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"}});
}

13
задан Community 23 May 2017 в 10:28
поделиться

4 ответа

Причина, по которой он не работает при прямой передаче аргументов в DynamicInvoke(), заключается в том, что DynamicInvoke() ожидает массив объектов, один элемент для каждого параметра целевого метода, и компилятор будет интерпретировать один массив как массив params для DynamicInvoke() вместо одного аргумента целевого метода (если вы не преобразовать его в единый объект).

Вы также можете вызвать DynamicInvoke(), передав массив, содержащий массив параметров целевого метода. Внешний массив будет принят в качестве аргумента для единственного параметра params DynamicInvoke(), а внутренний массив будет принят в качестве массива 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"
}
15
ответ дан 2 December 2019 в 00:02
поделиться

Я чувствую, что есть очень важный момент, который здесь не обсуждается, и это если вы определили тип делегата, который принимает params аргумент, нет особого смысла вообще вызывать для него DynamicInvoke. Я могу себе представить единственный сценарий, в котором это вступит в игру, если у вас есть делегат вашего пользовательского типа, и вы передаете его в качестве параметра какому-то методу, который принимает Делегата аргумент и вызывает DynamicInvoke для этот.

Но давайте посмотрим на этот код в обновлении ОП:

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");
0
ответ дан 2 December 2019 в 00:02
поделиться

Нет, но любой из принимаемых параметров может быть массивом.

Без подробностей, на этом все.

1
ответ дан 2 December 2019 в 00:02
поделиться

Нет, но с небольшой помощью можно почти подделать:

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

// :

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

CWL("{0}, {1}", Params(1,2));
0
ответ дан 2 December 2019 в 00:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: