Try/catch + using, правильный синтаксис

Какой из них:

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
}

Ответ 1

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

Ответ 2

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

var myObject = null;
try{
  myObject = new MyClass();
  //important stuff
} catch (Exception ex){
  //handle exception
} finally {
  if(myObject is IDisposable) ((IDisposable)myObject).Dispose();
}

Ответ 3

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

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

Но мне нравятся IDisposable и using, хотя я, возможно, смещен.

Ответ 4

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

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

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

Всякий раз, когда у меня есть scenerio, подобный этому, блок 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);
    }
}

Ответ 5

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

Ответ 6

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

Ответ 7

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

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

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

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

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