Должен ли я избежать альтернативного синтаксиса управления? - PullRequest
1 голос
/ 23 января 2009

Как программист-самоучка, у меня никогда не было никого, кто бы мог объяснить, почему определенные вещи следует или не следует использовать. Одним из примеров (который я использовал несколько лет назад и использую довольно часто) является синтаксис альтернативной структуры управления:

x = (y == true) ? "foo" : "bar";

Лично я нахожу этот синтаксис простым для понимания, особенно для короткого и лаконичного кода, но я не вижу, чтобы он получал широкое применение "в дикой природе", поэтому я хотел бы знать, если это плохая практика - использовать над более традиционной if ... else структурой?

Заранее спасибо.

Ответы [ 8 ]

13 голосов
/ 23 января 2009

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

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

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

2 голосов
/ 23 января 2009

Условный оператор (иногда называемый троичным оператором, но это технически неверно, см. Комментарии Марка) на самом деле не является «альтернативной структурой управления», есть несколько важных отличий:

  • Условный оператор является оператором и предоставляет значение, оно используется в выражении.
  • Если / else является управляющей структурой, она (конечно) сама по себе не возвращает никакого значения.
  • Альтернативами в условном операторе также должны быть выражения.
  • Альтернативой в структуре if-else может быть произвольное количество операторов.

Конечно, есть и сходство:

  • Каждый оценивает условное выражение.
  • Только соответствующая альтернатива (выражение или блок) оценивается на основе логического значения условия.
  • Оба могут быть объединены в цепочку вместе с другими в своем роде для формирования более длинных «переключаемых» операторов.

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

Если все следующее верно, используйте условное выражение:

  • Ваши условные и альтернативные утверждения легко понять.
  • Ни одно из выражений не имеет побочных эффектов.
  • Вам не понадобится дополнительное поведение (то есть побочные эффекты или дополнительные утверждения) в отношении альтернатив в будущем.

Ваш приведенный пример - хорошее использование троичного условного выражения.

Если сомневаетесь, используйте if-else. Остерегайтесь думать об условном как о другом типе «если-еще» и пытаться втиснуть вещи, которые ему не принадлежат. Именно такие вещи (особенно когда они встречаются в устаревшем коде) вообще отключают людей от условного оператора.

1 голос
/ 23 января 2009

Это известно как троичное выражение. Если цель может быть четко и кратко изложена с помощью троичного оператора, тогда я так и сделаю. Я обычно рисую линию и имею составные выражения (более 1 в сочетании с && или ||)

Хорошо:

var x = (someVar > 42 ) ? ThisFunction() : ThisOtherFunction();

Bad:

var x = (someVar > 42 && anotherVariable.IsSafeForConsumption() && IsNotProcessing ) ? ThisFunction() : ThisOTherFunction();
1 голос
/ 23 января 2009

Синтаксис, на который вы ссылаетесь, часто называют троичным условным оператором , и он семантически равен предложению if / else и выполняет то же самое.

Основное возражение против чрезмерного использования этих конструкций заключается в том, что он может создавать несколько грязный исходный код, который может быть не таким читаемым, как при использовании метода if / else. Это особенно верно для людей, которые не знают об этом конкретном синтаксисе. гораздо вероятнее 100% безопасно предположить, что люди понимают, если / еще.

0 голосов
/ 28 января 2009

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

x = (y == true) ? "foo" : "bar";
string instructions = "Please can somebody go and get me a " + x;

и преобразовать его в это:

string instructions = "Please can somebody go and get me a " + 
                      ((y == true) ? "foo" : "bar");

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

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

В слегка не связанной записке, пожалуйста, ради бога, никогда не пишите такой код (я видел это много раз):

if (y == true) {
   weWantAFoo = true;
}
else {
   weWantAFoo = false;
}

Вместо этого вы должны сделать это:

bool weWantAFoo = (y==true);

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

0 голосов
/ 23 января 2009

За исключением случаев, когда он используется в самых основных сценариях, я скажу избегать этого. Если 2 конструкции скомпилированы в один и тот же MSIL, зачем использовать ту, которая трудна для понимания?

0 голосов
/ 23 января 2009

Для меня это проблема читаемости и удобства обслуживания в многопрограммной среде.

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

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

  • Не усложняйте
  • Если это становится даже немного трудно читать, рефакторинг, если {} else {}
0 голосов
/ 23 января 2009

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

x = y ? "foo" : "bar";

за которым я довольно легко следую. ==true / ==false кажется (IMO) излишним для bools. Более распространенное использование "старого мира":

if(12345 == someVar) {...} // etc

Эта переменная "const ==" предназначена для того, чтобы избежать проблемы "=" vs "==", но, поскольку C # не рассматривает числа как логические значения, это очень редко, так как общий (в C #), чтобы увидеть яснее:

if(someVar == 12345) {...} // etc

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

...