С# Вложенные команды Try Catch или методы?
Простой вопрос с лучшей практикой.
Если вы вставляете try catch catch или используете только методы.
Например, если у вас есть метод, который открывает файл, он работает и закрывает файл, у вас будет открытый и закрытый за пределами try catch или, скорее, закрытие в блоке finally.
Теперь, если ваш открытый метод завершился неудачно, метод будет утверждать правильно? Итак, должен ли ваш обертку в try catch block или должен быть вызван из другого метода, который, в свою очередь, как блок catch catch?
Ответы
Ответ 1
В контексте метода, который открывает файл, я бы использовал оператор using vs 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();
}
Ответ 2
Теперь, когда у нас есть lambdas и тип вывода и некоторые другие вещи, есть идиома, которая распространена на других языках, что теперь имеет большой смысл в С#. Ваш пример был об открытии файла, что-то к нему, а затем его закрытии. Итак, теперь вы можете создать вспомогательный метод, который открывает файл, а также заботится о том, чтобы закрыть/удалить/очистить, но обращается к лямбда, которую вы предоставляете для части "do stuff". Это поможет вам получить сложный файл try/catch/finally для удаления/очистки прямо в одном месте, а затем использовать его снова и снова.
Вот пример:
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);
}
});
Ответ 3
Это вопрос стиля, но для меня я стараюсь никогда не использовать более одного уровня try/catch/finally в одном методе. В момент, когда вы нажмете вложенную попытку, вы почти наверняка нарушили 1 функцию = 1, и должны использовать второй метод.
Ответ 4
Зависит от того, что вы пытаетесь сделать, но в большинстве случаев вложенные try/catch являются признаком чрезмерно сложной функции (или программиста, который не совсем знает, как работают исключения).
В случае открытого файла я использую IDisposable-держатель и предложение use, и поэтому отказываюсь от необходимости явного try/catch.
Ответ 5
Как насчет того, где у вас есть связанный код, который не обязательно принадлежит отдельной функции от его собственного права? Правильно ли это?
try
{
// Part 1 Code Here
try
{
// Part 2 Code Here
}
catch (Exception ex)
{
// Error from Part 2
}
}
catch (Exception ex)
{
// Error from Part 1
}
Ответ 6
В большинстве случаев я разбивал вложенные блоки try/catch в функции. Но я иногда написал код, чтобы поймать и занести в журнал все неперехваченные исключения, брошенные моим приложением. Но что произойдет, если код регистрации завершится неудачно? Таким образом, у меня есть еще одна попытка/уловка, чтобы не допустить, чтобы пользователь видел диалоговое окно исключения необработанных исключений по умолчанию .NET. Но даже этот код может быть легко реорганизован в функции вместо вложенных блоков try/catch.
try
{
try
{
DoEverything();
}
catch (Exception ex)
{
// Log the exception here
}
}
catch (Exception ex)
{
// Wow, even the log is broken ...
}
Ответ 7
//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 } catch (Exception ex) { // Записываем исключение здесь }
Ответ 8
try
{
----
}
catch
{
try
{
---
}
catch
{
---
}
}