Подтвердить что ты не робот

Можно ли использовать необязательные/стандартные параметры в выражении лямбда в С#?

Есть ли способ использовать необязательные аргументы (параметры по умолчанию) с лямбда-выражения в С#? Я прочитал документацию, но не могу найти ничего, чтобы сказать так или иначе.

Чтобы проиллюстрировать, я могу определить простой метод, который использует необязательный аргумент для предоставления значения по умолчанию следующим образом:

void MyMethod(string arg = "default-value")
{ 
    Console.WriteLine(arg);
}

Я хочу знать, если я могу сделать то же самое, используя выражение лямбда.

// gives a syntax error
Action<string> MyMethod = (arg = "default") => Console.WriteLine(arg);

Я могу работать в необязательном параметре со значением по умолчанию, используя делегат, но это кажется немного неуклюжим.

delegate void MyDelegate(string arg = "default");
MyDelegate MyMethod = arg => Console.WriteLine(arg);

В качестве альтернативы я мог бы проверить параметр в лямбда-теле, что-то вроде...

 Action<string> MyMethod = (arg) => Console.WriteLine(string.IsNullOrEmpty(arg) ?
                                    "default" :
                                    arg);

Но снова это кажется немного неуклюжим.

Можно ли использовать необязательные параметры для установки значения по умолчанию в выражении лямбда в С#?

4b9b3361

Ответ 1

Нет. Вызывающий (код, вызывающий делегат) не "видит" лямбда-выражение, поэтому нет смысла указывать здесь параметр по умолчанию. Весь вызывающий абонент видит делегата. В вашем случае, например, вызывающий код знает только о Action<string> - как компилятор должен знать, чтобы указать значение по умолчанию, указанное в выражении лямбда?

В качестве примера того, как все становится сложно, представьте, что это было бы жизнеспособным. Затем рассмотрим этот код:

Action<string> action;
if (DateTime.Today.Day > 10)
{
    action = (string arg = "boo") => Console.WriteLine(arg); 
}
else
{
    action = (string arg = "hiss") Console.WriteLine(arg);
}
action(); // What would the compiler do here?

Имейте в виду, что аргумент предоставляется компилятором на сайте вызова - так что же делать с конечной строкой?

Это немного похоже на наличие интерфейса и реализации - если у вас есть параметр по умолчанию на интерфейсе, это прекрасно; если у вас есть только его реализация, то это будут видеть только те, кто знает конкретную реализацию. В случае лямбда-выражений действительно нет видимой реализации для вызывающего абонента: есть только подпись делегата.

Ответ 2

Лямбда будет соответствовать любой подписью назначенного ей делегата; без назначения делегату, лямбда не может компилироваться.

Если делегат содержит необязательные аргументы, то использование этого делегата необязательно может содержать аргументы. Если делегат не делает этого, то использование этого делегата не может опустить никаких аргументов.

Хотя делегаты Action и Func очень удобны и могут представлять большинство подписей, они не могут представлять какую-либо подпись с необязательными аргументами; вы должны использовать для этого другое определение делегата.

Remeber, Action и Func не особо особенны, они всего лишь два делегата, которые каждый использует, чтобы им не нужно было беспокоиться о создании своих собственных для каждой мелочи.