Какой код более читабелен? - PullRequest
32 голосов
/ 09 октября 2009

Предположим, у меня есть два метода bool Foo() и bool Bar(). Что из следующего более читабельно?

if(Foo())
{
    SomeProperty = Bar();
}
else
{
    SomeProperty = false;
}

или

SomeProperty = Foo() && Bar();

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

Что вы думаете? Есть ли другие факторы, которые влияют на решение? Например, если выражение && длиннее, чем одна строка, которая может уместиться на экране, я должен предпочесть первое?


Пояснения после ответа:

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

  • Bar() может быть дороже, чем Foo(), но ни у одного метода не должно быть побочных эффектов.
  • Оба метода названы более правильно, не так, как в этом примере. Foo() сводится к чему-то вроде CurrentUserAllowedToDoX() и Bar() больше похоже на XCanBeDone()

Ответы [ 21 ]

1 голос
/ 09 октября 2009

Если первая версия выглядела так:

if (Foo() && Bar())
{
    SomeProperty = true;
}
else
{
    SomeProperty = false;
}

или как это:

if (Foo())
{
    if (Bar())
       SomeProperty = true;
    else
       SomeProperty = false;
}
else
{
    SomeProperty = false;
}

Тогда это будет, по крайней мере, последовательным . Таким образом, следовать логике гораздо сложнее, чем во втором случае.

1 голос
/ 09 октября 2009

Если, как вы указываете, Bar () имеет побочные эффекты, я бы предпочел более явный способ. В противном случае некоторые люди могут не осознавать, что вы собираетесь воспользоваться короткими замыканиями.

Если Bar () самодостаточен, я бы выбрал более сжатый способ выражения кода.

1 голос
/ 09 октября 2009

Я бы выбрал длинную версию, потому что на первый взгляд понятно, что она делает. Во второй версии вы должны остановиться на несколько секунд, пока не поймете поведение оператора && при коротком замыкании. Это умный код, но не читаемый код.

1 голос
/ 09 октября 2009

Я думаю, что лучше всего использовать SomeProperty = Foo() && Bar(), потому что он намного короче. Я думаю, что любой нормальный .NET-программист должен знать, как работает && - оператор.

1 голос
/ 09 октября 2009

Подожди минутку. Эти заявления даже не эквивалентны, не так ли? Я смотрел на них несколько раз, и они не оценивают одно и то же.

Сокращением для первой версии будет использование троичного оператора, а не оператора "и".

SomeProperty = foo() ? bar: false

Однако, за исключением логической ошибки, я согласен со всеми, что более короткая версия более читабельна.

Редактировать - Добавлено

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

Изменить еще раз - добавлено больше:

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

1 голос
/ 09 октября 2009

часто бывает полезно, чтобы быть в состоянии останова любой конкретный вызов функции по отдельности, а также какой-либо конкретной настройки переменной для конкретного значения - это, возможно, спорное, я был бы склонен идти на первый вариант. Это дает больше шансов разрешить точные точки останова во всех отладчиках (что в случае с C # не очень большое число).

Таким образом, точка останова может быть установлена ​​перед вызовом Foo (), перед вызовом Bar () (и набором переменной), и когда переменная установлена ​​в false - и, очевидно, те же самые точки останова может также использоваться для отлова случаев Foo () и! Foo (), в зависимости от вопроса, который вы имеете в виду.

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

(C # компилируется быстро, поэтому переставить код обычно не большая проблема, но это отвлекает).

0 голосов
/ 09 октября 2009

Первый метод более читабелен, но получает больше строк кода, второй более ЭФФЕКТИВЕН, без сравнения, только одна строка! Я думаю, что второе лучше

0 голосов
/ 09 октября 2009

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

Первый способ проясняет случайному наблюдателю, что вы не выполняете Bar (), если Foo () не вернет true. Я понял, что логика короткого замыкания будет препятствовать вызову Bar () во втором примере (и я мог бы написать это сам), но первый способ на первый взгляд гораздо более преднамеренный.

0 голосов
/ 09 октября 2009

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

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

Так что, если Boo () никогда не должен вызываться, когда Foo () возвращает false, я бы выбрал версию №2, хотя бы только в качестве защитного метода программирования.

0 голосов
/ 09 октября 2009

Поскольку вы используете c #, я бы выбрал первую версию или использовал троичный оператор ?:. Использование && таким образом не является обычной идиомой в c #, так что вы, скорее всего, будете неправильно поняты. В некоторых других языках (на ум приходит Ruby) шаблон && более популярен, и я бы сказал, что он уместен в этом контексте.

...