Ответ 1
Я предпочитаю второй. Также могут быть ошибки ловушки, связанные с созданием объекта.
Какой из них:
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
}
Я предпочитаю второй. Также могут быть ошибки ловушки, связанные с созданием объекта.
Поскольку используемый блок - это просто синтаксическое упрощение 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();
}
Это зависит. Если вы используете Windows Communication Foundation (WCF), using(...) { try... }
не будет работать корректно, если оператор proxy в using
находится в состоянии исключения, т.е. Удаление этого прокси приведет к другому исключению.
Лично я верю в минимальный подход к управлению, т.е. обрабатываю только исключение, о котором вы знаете в момент выполнения. Другими словами, если вы знаете, что инициализация переменной в using
может вызвать конкретное исключение, я завершаю ее с помощью try-catch
. Точно так же, если внутри тела using
может произойти что-то, что напрямую не связано с переменной в using
, я переношу ее другим try
для этого конкретного исключения. Я редко использую Exception
в своих catch
es.
Но мне нравятся IDisposable
и using
, хотя я, возможно, смещен.
Если ваш оператор 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);
}
}
Оба являются допустимым синтаксисом. Это действительно сводится к тому, что вы хотите сделать: если вы хотите поймать ошибки, связанные с созданием/удалением объекта, используйте второй. Если нет, используйте первый.
Есть одна важная вещь, которую я буду здесь вызывать: первая будет не улавливать любое исключение, возникающее из вызова конструктора MyClass
.
Если объект, который вы инициализируете в блоке Using(), может вызывать любое исключение, тогда вы должны перейти ко второму синтаксису, в противном случае как в равной степени.
В моем сценарии мне пришлось открыть файл, и я передавал filePath в конструкторе объекта, который я инициализировал в блоке Using(), и он может генерировать исключение, если filePath неверно/пусто. Поэтому в этом случае имеет смысл второй синтаксис.
Мой пример кода: -
try
{
using (var obj= new MyClass("fileName.extension"))
{
}
}
catch(Exception ex)
{
//Take actions according to the exception.
}