Рекомендации по использованию лямбда-выражений для обработчиков событий
После обнаружения лямбда-выражений и их использования в качестве анонимных функций, я обнаружил, что написал много более тривиальных событий, таких как:
txtLogin.GotFocus += (o, e) =>
{
txtLogin.Text = string.Empty;
txtLogin.ForeColor = SystemColors.ControlText;
};
txtLogin.LostFocus += (o, e) =>
{
txtLogin.Text = "Login...";
txtLogin.ForeColor = SystemColors.InactiveCaptionText;
};
Я также отошел от обработчиков событий, которые просто вызывают другие функции, заменяя их небольшими лямбдами, которые делают то же самое:
backgroundWorker.DoWork += (o, e) => DatabaseLookup.Open(e.Argument as string);
Я нашел некоторые аналогичные вопросы, касающиеся производительности и указывая, что вы не можете удалить их, но я не нашел адресации, простой вопрос о - это хорошая идея?
Является ли использование лямбда таким образом, который считается хорошей формой, или больше опыта программистов смотреть на это? Скрывает ли он обработчики событий в труднодоступных местах или выполняет ли он код службы, уменьшая количество тривиальных обработчиков событий?
Ответы
Ответ 1
Это вполне разумная идея - но в этом конкретном случае вместо этого я использовал бы анонимный метод:
txtLogin.LostFocus += delegate
{
txtLogin.Text = "Login...";
txtLogin.ForeColor = SystemColors.InactiveCaptionText;
};
Преимущество состоит в том, что вам не нужно указывать параметры, что делает его более понятным, чтобы вы их не использовали. Это единственное преимущество, которое анонимные методы имеют над лямбда-выражениями.
Достижение производительности почти всегда будет незначительным. Неспособность удалить их впоследствии является очень реальной проблемой, если вам нужно удалить обработчик, но я нахожу, что часто этого не происходит. (Reactive Extensions имеет хороший подход к этому - когда вы подписываетесь на наблюдаемую последовательность, вам возвращается IDisposable
, которая удалит подписку, если вы ее назовете. Очень аккуратно.)
Ответ 2
Собственно, он считает, что он помещает обработчики событий в удобные для поиска места, а именно рядом с именем назначенного ему события.
В большинстве случаев вы увидите обработчики событий, например:
void Text1_KeyDown(....) {....}
прикрепленный к событию KeyUp txtFirstName, потому что после использования Intellisense для создания обработчика кто-то решил переименовать текстовое поле и что KeyUp работал лучше. С помощью Lambda объект, событие и функция все вместе.
Ответ 3
Это сложный вопрос. Я помню, как читал в Code Complete о том, как некоторые (умные) люди говорят, что вы должны максимально контролировать поток управления, при этом многие спорят о точки входа и выхода из метода, потому что это не делает программу более трудной для выполнения.
Лямбдас становится еще далеким от этого, поэтому в некоторых случаях очень сложно следить за тем, что происходит, при этом контроль прыгает с места на место.
В принципе, я думаю, что из-за этого, вероятно, это плохая идея, но она также эффективна и облегчает жизнь. Я, конечно, использую их в достаточной сумме. Вкратце, используйте с осторожностью!