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

Хочу рассказать о том, как сократить
try
{
  SomeObject.DoSomething();
}
catch (Exception ex)
{
  SomeExceptionHandlingFunction(ex);
}
до
ExecuteWithTryCatch(() => SomeObject.DoSomething());

Приведу фрагмент кода до изменения:
void AcceptChanges_Executed(object sender, CommandExecutedEventArgs e)
{
  var grid = FindCurrentTable();
  if (grid != null)
  {
     try
     {
       Program.ClassbookDb.CommitChanges(grid));
     }
     catch (Exception ex)
     {
       Program.PostException(ex);
     }
  }
}
После того, как я 3 раза написал подобный код, я решил вынести блок try… catch в отдельную функцию, которая в качестве параметра будет принимать ту функцию, которую надо выполнить внутри блока:
public delegate void TryCatchDelegate();

private void ExecuteWithTryCatch(TryCatchDelegate tcd)
{
  try
  {
    tcd();
  }
  catch (Exception ex)
  {
    Program.PostException(ex);
  }
}
После чего код функции AcceptChanges_Executed сократился до
void AcceptChanges_Executed(object sender, CommandExecutedEventArgs e)
{
  var grid = FindCurrentTable();
  if (grid != null)
    ExecuteWithTryCatch(() => Program.ClassbookDb.CommitChanges(grid));
}
Другой пример использования:
private void MainForm_Load(object sender, EventArgs e)
{
  ExecuteWithTryCatch(() => {
                              dgvTeachers.DataSource = Program.ClassbookDb.GetBindingSource("select person_id, person_fullname, person_birthdate, postal_code, postal_address from persons where persons.group_id is null");
                              dgvTeachers.Columns[0].HeaderText = "ID";
                              dgvTeachers.Columns[0].Visible = false;
                              dgvTeachers.Columns[1].HeaderText = "ФИО";
                              dgvTeachers.Columns[2].HeaderText = "Дата рождения";
                              dgvTeachers.Columns[3].HeaderText = "Почтовый индекс";
                              dgvTeachers.Columns[4].HeaderText = "Почтовый адрес";
                            });
  // Задаём обработчик для команды сохранения изменений
  ApplicationCommands.AcceptChanges.Executed += AcceptChanges_Executed;
  // Задаём обработчик для команды сброса изменений в таблице
  ApplicationCommands.ResetChanges.Executed += (obj, args) =>
                                                             {
                                                                 var grid = FindCurrentTable();
                                                                 if (grid != null)
                                                                    ExecuteWithTryCatch(() => Program.ClassbookDb.ReloadTable(grid));
                                                             };
  tbTeachers.Pressed = true;
}
Таким образом, можно любую повторяемую в нескольких методах конструкцию вынести в отдельный метод.

Комментарии (3)

RSS свернуть / развернуть
+
0
отличный прием, спасибо!
очень понравилось :)

BTW, на правах модератора
вынес этот пост в блог C# и вывел на главную ;)
avatar

NetCoder

  • 7 мая 2010, 20:28
+
0
я случайно перенес пост обратно своим редактированием…
зато понял когда надо использовать cut :)
avatar

lifehack

  • 8 мая 2010, 17:35
+
0
it's ok
поправил
avatar

NetCoder

  • 8 мая 2010, 22:35

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.