День 1339. #ЗаметкиНаПолях
Пустые Переменные в Лямбдах
В твиттере задали интересный вопрос:
Имеет ли смысл использование пустой переменной (дискарда) `_` в выражении типа?
— Layla #WomenOfDotNet (@LaylaCodesIt)
Короткий ответ: да. Но кому нужны простые ответы? Пустые переменные появились в C# недавно. А это значит, что не всё так просто, как кажется.
В C# есть несколько мест, где мы используем
Зачем это нужно?
Иногда мы вынуждены принимать аргументы, которые не будем использовать. Неиспользуемые параметры выглядят так, как будто это может быть ошибкой:
Поэтому принято соглашение об использовании
Использование
Всё становится ещё интереснее, когда
Источник: https://endjin.com/blog/2022/09/csharp-lambda-discards
Пустые Переменные в Лямбдах
В твиттере задали интересный вопрос:
Имеет ли смысл использование пустой переменной (дискарда) `_` в выражении типа?
( _ , args) =>{…}
Я ожидаю параметр, но не буду с ним ничего делать.— Layla #WomenOfDotNet (@LaylaCodesIt)
Короткий ответ: да. Но кому нужны простые ответы? Пустые переменные появились в C# недавно. А это значит, что не всё так просто, как кажется.
В C# есть несколько мест, где мы используем
_ как пустую переменную. В примере ниже _ технически не является ей:Func<int, int, int> f = (_, x) => 2 * x;Лямбда здесь имеет два параметра, первый называется
_, а второй называется x. C# принимает _ в качестве идентификатора в соответствии с правилами языка. Даже Visual Studio при наведении курсора на _ показывает подсказку «(parameter) int _». Мы можем продемонстрировать это, используя оба параметра:Func<int, int, int> f2 = (_, x) => _ * x;Следующий код не работал в C#8, но C#9 позволяет так писать:
Func<int, int, int> f3 = (_, _) => 42;Здесь символы подчеркивания действительно являются пустыми переменными. (Правило состоит в том, что если лямбда имеет несколько параметров с именем
_, то все они отбрасываются). A Visual Studio при наведении курсора на _ показывает подсказку «(discard) int _». Однако это работает только для лямбда-выражений.Зачем это нужно?
Иногда мы вынуждены принимать аргументы, которые не будем использовать. Неиспользуемые параметры выглядят так, как будто это может быть ошибкой:
void ShowNumber(int i)Анализатор кода не выдаёт даже предупреждения, а выдаёт только сообщение IDE0060 уровня Message о неиспользуемой переменной. Однако читателю этого кода неочевидно, есть ли ошибка в коде метода или так и задумано. При этом, если вы фанат чистых сборок — без предупреждений и сообщений анализатора, — тогда изменения кода, приводящие к появлению новых сообщений, немедленно привлекут ваше внимание.
{
Console.WriteLine(42);
}
Поэтому принято соглашение об использовании
_ в качестве имени параметра, который бы намеренно игнорировался. Если вы измените предыдущий пример, переименовав параметр i в _, вы увидите, что компилятор перестанет выдавать сообщение IDE0060, поскольку он знает об этом соглашении:void ShowNumber(int _)Но, если у вас есть два параметра, которые вы хотите игнорировать:
void ShowNumber(int _, int _)это вызовет ошибку компиляции CS0100 из-за дублирующего имени параметра
_, т.к. пустые переменные можно использовать только в лямбдах.Использование
_ - это просто соглашение. Это валидное имя для параметра, поэтому у нас не может быть двух параметров с именами _ по той же причине, по которой мы не можем иметь два параметра с именем i.Всё становится ещё интереснее, когда
_ используется в качестве имени локальной переменной. Например, что, по-вашему, выведет код с картинки ниже в C#9+?Источник: https://endjin.com/blog/2022/09/csharp-lambda-discards
👍5