попробуйте / поймать + используя правильный синтаксис - PullRequest
172 голосов
/ 04 января 2011

Какой:

using (var myObject = new MyClass())
{
   try
   {
      // something here...
   }
   catch(Exception ex)
   {
      // Handle exception
   }
}

ИЛИ

try
{
   using (var myObject = new MyClass())
   {
      // something here...
   }
}
catch(Exception ex)
{
   // Handle exception
}

Ответы [ 7 ]

88 голосов
/ 04 января 2011

Я предпочитаю второй.Также может отлавливать ошибки, связанные с созданием объекта.

34 голосов
/ 04 января 2011

Поскольку использование блока - это просто упрощение синтаксиса попытки / окончания ( MSDN ), лично я хотел бы пойти на следующее, хотя я сомневаюсь, что он значительно отличается от вашего второго варианта:

MyClass myObject = null;
try {
  myObject = new MyClass();
  //important stuff
} catch (Exception ex) {
  //handle exception
} finally {
  if(myObject is IDisposable) myObject.Dispose();
}
19 голосов
/ 04 января 2011

Это зависит. Если вы используете Windows Communication Foundation (WCF), using(...) { try... } не будет работать правильно, если прокси в операторе using находится в состоянии исключения, т.е. удаление этого прокси вызовет еще одно исключение.

Лично я верю в минимальный подход к обработке, т. Е. Обрабатывать только те исключения, которые вам известны в момент исполнения. Другими словами, если вы знаете, что инициализация переменной в using может вызвать конкретное исключение, я заключаю его в try-catch. Точно так же, если внутри using body может произойти что-то, что не имеет прямого отношения к переменной в using, то я обертываю это другим try для этого конкретного исключения. Я редко использую Exception в моих catch es.

Но мне нравятся IDisposable и using, хотя, возможно, я предвзятый.

18 голосов
/ 27 мая 2011

Если вашему оператору catch нужно получить доступ к переменной, объявленной в операторе using, то внутри - ваш единственный вариант.

Если вашему выражению catch требуется объект, на который ссылается использование, до его удаления, то внутри - ваш единственный вариант.

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

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

Итак, мое общее рекомендация - снаружи, далеко снаружи.

private void saveButton_Click(object sender, EventArgs args)
{
    try
    {
        SaveFile(myFile); // The using statement will appear somewhere in here.
    }
    catch (IOException ex)
    {
        MessageBox.Show(ex.Message);
    }
}
9 голосов
/ 04 января 2011

Оба допустимых синтаксиса.Это действительно сводится к тому, что вы хотите сделать: если вы хотите отлавливать ошибки, связанные с созданием / удалением объекта, используйте второй.Если нет, используйте первый.

6 голосов
/ 04 января 2011

Есть одна важная вещь, которую я здесь назову: первая будет не перехватывать любые исключения, возникающие из-за вызова конструктора MyClass.

1 голос
/ 27 декабря 2017

Если объект, который вы инициализируете в блоке Using (), может выдать какое-либо исключение, вам следует использовать второй синтаксис, в противном случае оба значения одинаково действительны.

В моем сценарии мне пришлось открыть файл иЯ передавал filePath в конструктор объекта, который я инициализировал в блоке Using (), и он может выдать исключение, если filePath неверен / пуст.Так что в этом случае второй синтаксис имеет смысл.

Мой пример кода: -

try
{
    using (var obj= new MyClass("fileName.extension"))
    {

    }
}
catch(Exception ex)
{
     //Take actions according to the exception.
}
...