Подтвердить что ты не робот

Как решить, использовать ли /else vs try/catch?

При написании кода, как решить, как использовать if/else или try/catch? Например, при проверке файла, должно ли оно основываться на if/else (if (File.Exists)) или блоке try/catch?

Например, запись в файл может быть обработана с помощью блока if/else для создания файла, а затем записи на него или try/catch с предположением, что файл существует. Какие существуют соображения при выборе?

Спасибо

4b9b3361

Ответ 1

Вы не должны использовать try/catch для управления потоком.

Генерация исключения - чрезвычайно дорогостоящее действие. Если /else намного быстрее и чище.

Ответ 2

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

Рассмотрим следующий бит кода:

if(File.Exists("file.txt"))
    File.Delete("file.txt")

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

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

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

Ответ 3

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

В противном случае, если он иногда преуспевает и иногда терпит неудачу - и делает это по определенной причине, используйте if/else (это называется обработкой структурированных исключений).

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

Ответ 4

Вы используете try/catch, когда может произойти что-то неожиданное (исключение), и вы хотите сделать что-то особенное, например:

try
{
   //Do something that might rise an exception, say a division by 0
   //this is just an easy example as you might want to check if said value is not 0
   //before dividing
   int result = someNumberOfMine / anUnsafeNumber;
}
catch
{
   //if something unexpected happened, do a special treament
}

В вашем конкретном случае я рекомендовал бы использовать File.Exists, чтобы проверить наличие файла вместо использования блока try/catch, поскольку присутствие или отсутствие файла можно проверить, прежде чем что-либо делать с ним.

Ответ 5

Просто чтобы поставить тему на отдых (да, вопрос был поставлен 8 месяцев назад, но Интернет всегда знает!), я решил запустить небольшой тест, для которого более эффективный , если "Уверен, что у вас не будет исключения - например, часть" else "будет иметь место только 0,001% времени. Как оказалось, если вам никогда не придется ловить/что-то еще, попытка try-catch будет на 4% быстрее (на моей машине, во всяком случае). Здесь код и сопровождающие его результаты:

CASE 1: if-else:

var startTime = DateTime.Now;
int bazillion = 100000000;
int[] list = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
for (int i = 0; i < bazillion; i++)
{
    for (int k = 0; k < list.Length; k++)
    {
        if (k >= 0)
        {
            list[k] = i;
        }
        else
        {
            // do nothing.
        }
    }
}
var executionTime = DateTime.Now - startTime;
Debug.WriteLine (executionTime.TotalMilliseconds);

Время выполнения (миллисекунды) на 5 прогонов: 7441.4256, 7392.4228, 7545.4316, 7531.4308, 7323.4188.
Среднее = 7446,82592 миллисекунды


CASE 2: try-catch:

var startTime = DateTime.Now;
int bazillion = 100000000;
int[] list = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
for (int i = 0; i < bazillion; i++)
{
    for (int k = 0; k < list.Length; k++)
    {
        try
        {
            list[k] = i;
        }
        catch (Exception e)
        {
            // do nothing
        }
    }
}
var executionTime = DateTime.Now - startTime;
Debug.WriteLine(executionTime.TotalMilliseconds);

Время выполнения (миллисекунды) на 5 прогонов: 7258.4152, 7137.4083, 7070.4044, 7052.4033, 7120.4073 Среднее = 7127.8077 миллисекунд


Заключение (на основе этого довольно упрощенного примера, фактический пробег может отличаться и т.д.):
Что касается чистых чисел, если вы довольно уверенны в том, что случай exception/else не будет выполняться, try-catch будет примерно на 4% быстрее, чем выполнение предложения if if каждый раз.

Ответ 6

Исключительная обработка должна выполняться или использоваться только в исключительных случаях.

В сценарии, который зависит от того, существует ли файл или нет, нет смысла использовать блок catch try, когда вы просто можете сделать

if(File.Exists(path))
{
}
else
{

}

Исключительное обращение вызывает большую производительность, поэтому старайтесь свести к минимуму исключительные случаи, применяя больше проверки кода, например File.Exists(path))

Ответ 7

вообще зависит от

Для файлов, основанных на файлах, вы почти всегда хотите попробовать операцию и обработать сбои, а не сначала проверить. причина в том, что файловая система является общим ресурсом, и вы не можете гарантировать, что после того, как file.exists вернет true, файл существует, поскольку какой-то другой процесс мог удалить его в среднем времени.

Ответ 8

Как уже указывали некоторые ответы, это зависит.

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

Вы всегда можете прочитать эти статьи из Ned Batchelder (Переговоры о кодах возврата, в качестве альтернативы использованию исключений) и Joel Spolsky (Почему он не любит программирование с исключениями), чтобы понять, что другие думают об исключениях, а затем сделать свой собственный ум.

Ответ 9

Просто мысль... один из ответов заключался в том, что вы должны попытаться поймать, если, например, у вас есть возможность деления на нуль. Интересно, почему? Вы контролируете ситуацию, вы можете проверить, прежде чем делиться и действовать. Если он равен нулю, вам просто не нужно делать деление, а вместо этого выполнять другую логику.

Я бы использовал try catch только в том случае, если вы не контролируете или не можете (или не имеет смысла) проверять вещи заранее (открытие файла,...).

В вашем случае я бы использовал File.Exists и try/catch. File.Exists как проверка бизнеса (нет необходимости открывать его, когда он не существует), try/catch, чтобы поймать любые исключения, которые могут возникнуть при открытии файла.

Ответ 10

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

Итак, основная идея: Старайтесь избегать исключений при ожидаемых обстоятельствах.

Ответ 11

Как правило, вы должны сделать то и другое. try/catch, чтобы избежать исключительных ситуаций (файл был внезапно удален из другого потока). И если /else обрабатывать не исключительные (проверьте, существует ли файл). Try/catch относительно медленнее обычного if/else, поэтому не стоит использовать его для всего.

Ответ 12

Послание "Исключения должны быть исключительными" полезно при принятии таких решений. Главным является то, что вы должны обрабатывать известные ситуации со стандартным потоком программ (то есть с операторами), чтобы исключения отображали непредвиденные ситуации (например, ошибки).

Конечно, как и любое правило, оно должно быть разбито.

Кроме того, я не стал бы слишком беспокоиться о влиянии обработки исключений на производительность. Накладные расходы в значительной степени незначительны во всех, кроме чрезвычайных ситуациях.

Ответ 13

Для этого вы знаете проблему выхода файла. Поэтому вы предпочитаете, если хотите.

Если вы не знаете проблему, лучше использовать try catch.

Я предлагаю обе, как ниже

try 
{
  if(File.Exists(path)) 
  { 
     do work
  } 
  else 
  {
     messagebox.show("File Path Not Exit");
  } 
}
catch(Exception e) 
{
 messagebox.show(e); 
}

он улавливает все ошибки, о которых мы не думаем.

Ответ 14

Как видно из всех ответов, нет стандартного/утвержденного способа решить, следует ли использовать тот или иной. Если все сделано правильно, оба метода будут эффективными. Если сделано неправильно, оба метода будут неэффективными.

Я предпочитаю, если /else, когда это имеет смысл (т.е. внутри моих собственных функций) и Try блоков, когда я вызываю функции, которые я не контролирую.

В приведенном выше примере File.Exists() будет достаточным, если вы будете управлять файлом (что означает, что никакая другая программа не может его манипулировать), но недостаточно, если есть вероятность, что файл будет удален между проверкой и использованием,

Файловые операции, как правило, лучше обрабатываются исключениями в большинстве случаев, по моему опыту, потому что эти очень файловые операции в С# создают исключения. Они не возвращают коды ошибок, которые можно проверить с помощью операторов if.