После обнаружения лямбда-выражений и их использования в качестве анонимных функций, я писал много большего количества тривиальных событий, таких как они:
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);
Я нашел некоторые подобные вопросы, обратившись к проблемам производительности и указав, что Вы не можете удалить их, но я не нашел, что кто-либо рассматривающий простой вопрос является этим хорошая идея?
Использование лямбд таким способом рассмотрено хорошей формой, или больше программистов опыта смотрит сверху на это? Это скрывает обработчики событий в дефицитных местах, или это делает код сервис путем сокращения количества тривиальных обработчиков событий?
Это вполне разумная идея, но в данном конкретном случае я бы использовал вместо этого анонимный метод:
txtLogin.LostFocus += delegate
{
txtLogin.Text = "Login...";
txtLogin.ForeColor = SystemColors.InactiveCaptionText;
};
Преимущество состоит в том, что вам не нужно указывать параметры - что делает более ясным, что вы не используете их. Это единственное преимущество анонимных методов перед лямбда-выражениями.
Падение производительности почти всегда будет незначительным. Невозможность удалить их впоследствии является очень реальной проблемой, если вы действительно нуждаетесь в возможности удалить обработчик, но я часто не могу этого сделать. (У Reactive Extensions есть хороший подход к этому - когда вы подписываетесь на наблюдаемую последовательность, вам возвращается IDisposable
, который удалит подписку, если вы ее вызовете. Очень удобно.)
На самом деле, считается, что обработчики событий помещаются в удобные для поиска места, а именно рядом с именем события, которому они назначены.
Часто вы увидите такие обработчики событий, как:
void Text1_KeyDown(....) {....}
, прикрепленные к событию KeyUp для txtFirstName, потому что после использования Intellisense для создания обработчика кто-то решил переименовать текстовое поле, и KeyUp работал лучше. В Lambda объект, событие и функция - все вместе.
Это непростой вопрос. Я помню, как читал в Code Complete о том, как некоторые (умные) люди говорят, что вы должны сохранять поток управления как можно более простым, при этом многие приводили доводы в пользу единственной точки входа и выхода из метода, потому что этого не делали программе труднее следовать.
Лямбды уходят еще дальше от этого, что в некоторых случаях очень затрудняет отслеживание того, что происходит, поскольку контроль перескакивает с места на место.
В принципе, я думаю, что это, вероятно, плохая идея из-за этого, но она также мощная и облегчает жизнь. Я, конечно, использую их в достаточном количестве. Таким образом, используйте с осторожностью!