Вопрос 1:
Это из-за возврата нового StreamReader (имя файла); внутри цикла? или тот факт, что вам не нужен цикл for в этом случае?
Стример не имеет к этому никакого отношения. Антишаблон возникает из - за четкий конфликт намерений между foreach
и if
:
Какова цель foreach
?
Я предполагаю, что ваш ответ будет что-то вроде: «Я хочу многократно выполнить определенный кусок кода»
Сколько файлов вы ожидаете обработать?
Поскольку у вас может быть только одно конкретное имя файла (включая расширение) в определенной папке, это доказывает, что ваш код предназначен для поиска одного применимого файла.
Это также подтверждается тем фактом, что вы немедленно возвращаете значение. Вы на самом деле не заботитесь о втором матче, даже если бы он существовал.
Бывают ситуации, когда это не анти-паттерн.
- Если вы также посмотрите в подкаталогах (
Directory.GetFiles(".", SearchOption.AllDirectories)
), то можно найти более одного файла с одинаковым именем файла (включая расширение)
- Если вы ищете частичные совпадения имен файлов (например, каждый файл, имя которого начинается с
"Test_"
, или каждый "*.zip"
файл.
Обратите внимание, что в обоих этих случаях вам потребуется обработать несколько совпадений и, следовательно, не вернуть значение сразу.
Вопрос 2:
Чтобы исправить второй пример, вы бы переписали его без оператора if и вместо этого окружили StreamReader блоком try-catch, и если он выдает исключение FileNotFoundException, вы обрабатываете его в блоке catch соответственно?
Исключения дорогие. Они никогда не должны использоваться вместо правильной логики потока. Исключения есть, поскольку их название предполагает исключительные обстоятельства.
По этой причине вы не должны удалять if
.
Согласно этому ответу на SoftwareEngineering.SE :
Как правило, использование исключений для потока управления является анти-паттерном с заметными ситуациями и специфическими для конкретного языка кашлями.
В качестве краткого изложения, почему, как правило, это анти-шаблон:
- Исключением являются, по сути, сложные заявления GOTO
- Программирование с исключениями, следовательно, приводит к более сложному чтению и пониманию кода
- Большинство языков имеют существующие структуры управления, предназначенные для решения ваших проблем без использования исключений.
- Аргументы в пользу эффективности, как правило, являются спорными для современных компиляторов, которые стремятся оптимизировать с предположением, что исключения не используются для потока управления.
Прочитайте обсуждение в вики Ward для получения более подробной информации.
Нужно ли вам обернуть это в try / catch, в значительной степени зависит от вашей ситуации:
- Насколько вероятно, что вы столкнетесь с условиями гонки?
- Вы действительно в состоянии справиться с этой ситуацией, или вы хотите, чтобы эта проблема всплыла перед пользователем, потому что вы не знаете, как справиться с этим.
Ничто не является вопросом «всегда используй это». Чтобы доказать мою точку зрения:
Отдельные исследования доказали, что у вас меньше шансов получить травму, если вы наденете защитный шлем, защитные очки и бронежилеты.
Так почему же мы не все время носим это защитное снаряжение?
Простой ответ заключается в том, что у них есть недостатки:
- Стоит денег
- Это делает ваше движение более громоздким
- Это может быть довольно тепло носить его.
Теперь мы добираемся куда-то: есть за и против . Другими словами, имеет смысл носить это оборудование только в тех случаях, когда профессионал перевешивает минусы.
- Строители гораздо чаще получают травмы во время работы. Им выгоден защитный шлем.
- Офисные работники, с другой стороны, имеют гораздо меньше шансов получить травму. Защитные шлемы не стоят того.
- Член команды спецназа гораздо более вероятен, чем офисный работник.
Стоит ли обернуть звонок в попытку / ловить? Это очень сильно зависит от того, перевешивает ли польза от этого затраты на его реализацию.
Обратите внимание, что другие могут утверждать, что для его обертывания требуется всего несколько нажатий клавиш, поэтому, очевидно, это следует сделать. Но это еще не весь аргумент:
- Вам нужно решить, что делать, как только вы поймаете исключение.
- Если в кодовой базе много разных обращений к разным файлам, решение обернуть один файл в попытку / отлов обычно означает, что вам нужно обернуть все эти случаи. Это может оказать существенное влияние на количество усилий, необходимых для его реализации.
- Это вполне возможно , что вы намеренно хотите не обрабатывать исключение.
- Обратите внимание, что ваше приложение должно будет обрабатывать исключение в какой-то момент, но это не обязательно сразу после возникновения исключения.
Так что выбор за вами. Есть ли польза от этого? Считаете ли вы, что это улучшает приложение, а не требует затрат на его реализацию?
Обновление - от комментария, который я написал, до другого ответа, так как я думаю, что это тоже актуально для вас:
Это очень сильно зависит от окружающего контекста.
- Если открытию потокового ридера предшествует
if(!File.Exists) File.Create()
, то отсутствие файла при открытии потокового ридера действительно исключительное .
- Если имя файла было выбрано из списка существующих файлов, его внезапное отсутствие снова является исключительным .
- Если вы работаете со строкой, которую вы еще не проверяли в каталоге; тогда отсутствие файла является вполне логичным результатом, и, следовательно, не исключительным .