C # Вложенные операторы или методы Try Catch? - PullRequest
17 голосов
/ 19 марта 2009

Простой вопрос передового опыта.

Если вы хотите использовать операторы catch или просто использовать методы.

Например, если у вас есть метод, который открывает файл, работает и закрывает файл, у вас будет открытие и закрытие за пределами попытки try или, скорее, закрытие в блоке finally.

Теперь, если ваш метод open потерпит неудачу, метод будет утверждать правильно? Так следует ли заключить это в блок try catch или это должно быть вызвано из другого метода, который, в свою очередь, является блоком try catch?

Ответы [ 8 ]

15 голосов
/ 19 марта 2009

В контексте метода, который открывает файл, я бы использовал оператор using против try catch. Оператор using обеспечивает вызов Dispose в случае возникновения исключения.

using (FileStream fs = new FileStream(file, FileMode.Open))
{
    //do stuff
}

делает то же самое, что и:

FileStream fs;
try
{
     fs = new FileStream(file, FileMode.Open);
     //do Stuff
 }
 finally
 {
        if(fs!=null)
           fs.Dispose();
 }
11 голосов
/ 20 марта 2009

Теперь, когда у нас есть лямбда-выражения, вывод типов и некоторые другие вещи, есть идиома, распространенная в других языках, которая теперь имеет большой смысл в C #. Ваш пример был о том, как открыть файл, что-то с ним сделать, а затем закрыть. Что ж, теперь вы можете создать вспомогательный метод, который открывает файл, а также заботится о том, чтобы обеспечить его закрытие / удаление / очистку, но вызывает лямбду, которую вы предоставляете для части «делать вещи». Это поможет вам собрать сложные вещи try / catch / finally dispose / cleanup прямо в одном месте, а затем использовать их снова и снова.

Вот пример:

public static void ProcessFile(string filePath, Action<File> fileProcessor)
{
  File openFile = null;

  try
  {
    openFile = File.Open(filePath); // I'm making this up ... point is you are acquiring a resource that needs to be cleaned up after.

    fileProcessor(openFile); 
  }
  finally
  {
    openFile.Close(); // Or dispose, or whatever.
  }
}

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

Helpers.ProcessFile("C://somefile.txt", f => 
 {
   while(var text = f.ReadLine())
   {
     Console.WriteLine(text);
   }
 });
7 голосов
/ 19 марта 2009

Это вопрос стиля, но для меня я стараюсь, чтобы в одном методе никогда не было более одного уровня вложенности try / catch / finally. В тот момент, когда вы нажали вложенную попытку, вы почти наверняка нарушили принцип действия 1 function = 1 и должны использовать второй метод.

4 голосов
/ 19 марта 2009

Зависит от того, что вы пытаетесь сделать, но в большинстве случаев вложенные try / catches являются признаком слишком сложной функции (или программиста, который не совсем знает, как работают исключения!).

В случае открытого файла, я бы использовал держатель IDisposable и предложение using, и поэтому отказался от необходимости какого-либо явного try / catch.

3 голосов
/ 01 июня 2011

Как насчет того, где у вас есть связанный код, который не обязательно принадлежит отдельной отдельной функции? Тогда это будет правильно?

try
{
  // Part 1 Code Here

  try
  {
    // Part 2 Code Here
  }
  catch (Exception ex)
  {
    // Error from Part 2
  }
}
catch (Exception ex) 
{
  // Error from Part 1
} 
1 голос
/ 19 марта 2009

Большую часть времени я бы разбивал вложенные блоки try / catch на функции. Но я иногда писал код для перехвата и регистрации всех необработанных исключений, выданных моим приложением. Но что, если код регистрации не будет выполнен? Поэтому у меня есть еще одна попытка / ловушка, чтобы пользователь не видел диалоговое окно необработанных исключений .NET по умолчанию. Но даже этот код может быть легко преобразован в функции вместо вложенных блоков try / catch.

try
{
    try
    {
        DoEverything(); 
    }
    catch (Exception ex)
    {
        // Log the exception here
    }
}
catch (Exception ex)
{
    // Wow, even the log is broken ...
}
0 голосов
/ 04 мая 2015
//create a switch here and set it to 0 
try
{
    DoChunk1(); 
    //looks good. set the switch to 1
}
catch (Exception ex)
{
    // Log the exception here
}

// проверяем переключатель, если он все еще равен нулю на этом этапе, вы можете остановить свою программу здесь; иначе установите переключатель обратно в ноль и выполните следующий оператор try catch. полностью согласен с их разбивкой как указано выше

попробовать { DoChunk2 (); //выглядит хорошо. установите переключатель в 1 } поймать (исключение ex) { // Записать исключение здесь }

0 голосов
/ 27 мая 2012
try 
{
  ----
}
catch
{
   try
      {
           ---
      }
   catch
      {
        ---
      }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...