Нужно ли писать еще часть в каждом условии if? - PullRequest
13 голосов
/ 03 августа 2010

Вопрос, который я задал, может быть закрыт, но я просто хочу знать, нужно ли писать еще часть каждого условия if.Один из моих старших программистов сказал мне, что «вы должны написать еще одну часть в каждом условии if».Предположим, у нас нет условия для записи в другой части, что мы должны делать?Я предполагаю, что здесь будет проходить здоровая дискуссия ....

Ответы [ 10 ]

16 голосов
/ 03 августа 2010

Это ужасная идея.В итоге вы получите код вида:

if (something) {
    doSomething();
} else {
}

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

8 голосов
/ 03 августа 2010

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

public void DoSomething(string text)
{
    if (text == null)
    {
        throw new ArgumentNullException("text");
    }
    // Do stuff
}

Теперь вы можете поместить основную работу метода в предложение "else" здесь - но это приведет к ненужному увеличению вложенности. Добавьте еще несколько условий, и все это станет нечитаемым беспорядком.

По моему опыту, эта схема "раннего выхода" достаточно распространена и касается как возвращаемых значений, так и исключений. Я знаю, что есть некоторые, которые предпочитают одну точку возврата из метода, но в языках, с которыми я работаю (Java, C #), это может привести к значительно менее читаемому коду и более глубокому вложению.

Теперь есть одна ситуация, когда есть больше возможностей для дебатов, и именно здесь обе ветви являются терминальными, но ни одна из них не является эффективным способом:

public int DoSomething()
{
    // Do some work
    if (conditionBasedOnPreviousWork)
    {
        log.Info("Condition met; returning discount");
        return discount;
    }
    else
    {
        log.Info("Condition not met; returning original price");
        return originalPrice;
    }
}

(Обратите внимание, что я намеренно дал обеим ветвям больше работы, чем просто возвращение - в противном случае было бы уместно условное выражение.)

Будет ли это более читабельным без "else"? Это действительно вопрос личного выбора, и я не собираюсь утверждать, что я всегда последовательный. Наличие одинакового отступа в обеих ветвях дает им одинаковый вес - и, возможно, поощряет возможность рефакторинга позже путем изменения условия ... тогда как, если мы только что вернулись к «возврату первоначальной цены», рефакторинг помещения этого в блок if и перемещение дисконтного регистра из блока if на первый взгляд было бы менее корректным.

4 голосов
/ 03 августа 2010

В императивных языках, таких как Java и C, if - else является оператором и не возвращает значение.Таким образом, вы можете с радостью написать только часть if и продолжать.И я думаю, что это лучшая практика, чем добавление пустых else с после каждого if.

Однако в функциональных языках, таких как Haskell и Clojure, if является выражением, и оно должно возвращать значение,Таким образом, это должно быть достигнуто с else.Однако все еще есть случаи, когда вам может не понадобиться раздел else.В таких случаях у Clojure есть макрос when, который переносит if - else и возвращает nil в разделе else, избегая его записи.

(when (met? somecondition)
  (dosomething))
4 голосов
/ 03 августа 2010

Опасность!Опасность, Уилл Робинсон!

http://en.wikipedia.org/wiki/Cargo_cult_programming

Будет ли включение пустых блоков else { } как-то улучшить качество, читаемость или надежность вашего кода?Я думаю, что нет.

1 голос
/ 24 января 2014

Глядя на это чисто с семантической точки зрения - я не могу придумать ни одного случая, когда не существует неявного другого для каждого if.

если машина не остановится до того, как я доберусь до стены, я упаду, иначе я не упаду.

За исключением семантики:

Ответ на этот вопрос зависит отокружение, и каков результат ошибки.

Бизнес-код?Делайте то, что говорят ваши стандарты кодирования.
ИМХО, вы обнаружите, что его написание, хотя поначалу кажется, что это слишком много работы, станет неоценимым через 10 лет, когда вы вернетесь к этому коду.Но, конечно, это не был бы конец света, если бы вы пропустили важное «анти-условие».

Однако: код безопасности, безопасности или жизненно важный код?Это другая история.

В этом случае вы хотите сделать две вещи.
Первое: вместо того, чтобы проверять неисправность, вы хотите доказать, что не неисправность.Это требует пессимистического взгляда на вход в любой модуль.Вы предполагаете, что все не так, пока не докажете, что это правильно.
Второе: в жизненно важной ситуации: вы НИКОГДА не хотите причинить боль пациенту. :

bool everyThingIsSafe = true;
if(darnThereIsAProblem())
{
   reportToUserEndOfWorld();
}
return everyThingIsSafe;

Упс.Я забыл установить EveryThingIsSafe false.
Подпрограмма, которая называет этот фрагмент, теперь обманывается.Если бы я инициализировал evertThingIsSafe в false - я всегда в безопасности, но теперь мне нужно предложение else, чтобы указать, что ошибки не было.
И да, я мог бы изменить это на положительный тест - но тогда мне нужноостальное для обработки ошибки.
И да, я мог бы назначить EveryThingIsSafe () немедленный возврат чека.А затем проверил флаг, чтобы сообщить о проблеме.Неявное другое, почему бы не быть явным?
Строго говоря, неявное иное, что это представляет, является разумным.
Для аудитора FDA / безопасности, возможно, нет.
Если это явное, может указать на тест, егоеще, и что я справился с обоими условиями четко.

Я кодирую медицинские устройства уже 25 лет.В этом случае вы хотите другое, вы хотите по умолчанию в этом случае, и они никогда не будут пустыми.Вы хотите точно знать, что произойдет, или как можно ближе.Потому что игнорирование условия может кого-то убить.

Посмотрите на Therac-25.8 тяжело ранен.3 мертвых.

0 голосов
/ 10 февраля 2015

Я знаю, что опоздал, но я много думал над этим и хотел поделиться своими результатами.

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

//negatives should be fixed
if(a < 0) {
    a+=m;
}
//else value is positive
0 голосов
/ 03 августа 2010

Это чисто вопрос стиля и ясности.Легко представить себе утверждения, особенно простые, для которых другое было бы совершенно лишним.Но когда у вас есть более сложное условное выражение, возможно, обрабатывающее множество различных случаев, часто бывает ясно, что явно объявить, что в противном случае ничего не должно быть сделано.В этих случаях я бы оставил комментарий // do nothing в противном случае пустым, чтобы было ясно, что пространство намеренно оставлено пустым.

0 голосов
/ 03 августа 2010

Иногда нет другой части .... и включение пустой только делает код менее читабельным imho.

0 голосов
/ 03 августа 2010

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

if (someCondition)
    bar();
    notbar();  //won't be run conditionally, though it looks like it might

foo();

Я бы написал

 if (someCondition){
        bar();
        notbar();  //will be run
 }
 foo();
0 голосов
/ 03 августа 2010

Нет, вам не нужно ..

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

...