Я прочитывал некоторый мой код C# сегодня и нашел эту строку:
if (ProgenyList.ItemContainerGenerator.Status != System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated) return;
Заметьте, что можно сказать, не прокручивая, что это, "если" оператор, который работает с ItemContainerGenerator. Состояние, но Вы не можете легко сказать что, если, "если" пункт оценивает к "истинному", метод возвратится в той точке.
Реалистично я должен был переместить оператор "возврата" в строку отдельно, но это получило меня думающий о языках, которые позволяют "затем" часть оператора сначала. Если бы C# разрешил его, то строка могла бы быть похожей на это:
return if (ProgenyList.ItemContainerGenerator.Status != System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated);
Это могло бы быть немного "спорно", но я задаюсь вопросом, какие люди думают об этом виде конструкции. Это могло бы служить для создания строк как та выше более читаемого, но это также могло бы иметь катастрофические последствия. Вообразите этот код:
return 3 if (x > y);
Логически мы можем только возвратиться, если x> y, потому что не "еще" существует, но часть меня смотрит на это и думает, "мы все еще возвращаемся если x <= y? Если так, что мы возвращаем?"
О чем Вы думаете "затем перед если" конструкция? Это существует на Вашем предпочтительном языке? Вы часто используете его? C# извлек бы выгоду из него?
Мне не нравится эта двусмысленность. Рассмотрим следующий код:
doSomething(x)
if (x > y);
doSomethingElse(y);
Что он делает? Да, компилятор мог это понять, но для программиста это выглядело бы довольно запутанным.
Давайте немного переформатируем это и посмотрим:
using System.Windows.Controls.Primitives;
...
if (ProgenyList.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
{
return;
}
Теперь насколько сложно увидеть оператор return? Признаем, что в SO вам все еще нужно прокручивать страницу, чтобы увидеть все условие, но в IDE вам не придется этого делать... частично из-за того, что вы не пытаетесь поместить условие и результат на одной строке, а частично из-за директивы using
.
Преимущество существующего синтаксиса C# в том, что текстовый порядок отражает порядок выполнения - если вы хотите знать, что произойдет, вы читаете код сверху вниз.
Лично я не поклонник "return if..." - я скорее переформатирую код для удобочитаемости, чем изменю порядок.
Считается грамматически некорректным ставить ответ перед вопросом, почему он должен отличаться в коде?
Это есть и в Perl, и в Ruby, и это прекрасно работает. Лично меня устраивает столько функциональности, сколько вы хотите мне подкинуть. Чем больше у меня возможностей для написания кода, тем лучше общее качество, верно? "Правильный инструмент для работы" и все такое.
Однако, с реалистичной точки зрения, это довольно спорный вопрос, поскольку уже довольно поздно для такого фундаментального дополнения в жизненном цикле C#. Мы находимся на том этапе, когда любое незначительное изменение синтаксиса потребует много работы для реализации из-за размера кода компилятора и его алгоритма разбора синтаксиса. Чтобы новое дополнение даже рассматривалось, оно должно принести довольно много функциональности, и это просто (не очень) другой способ сказать то же самое.
Я не вижу никаких проблем с
return 3 if (x > y);
Возможно, это беспокоит вас, потому что вы не привыкли к синтаксису. Также приятно иметь возможность сказать
return 3 unless y <= x
Это хорошая синтаксическая опция, но я не думаю, что она нужна c#.
Я думаю, что это нормально, если бы область была ограничена только операторами return
. Как я сказал в своем комментарии, представьте, если бы это было разрешено:
{
doSomething();
doSomethingElse();
// 50 lines...
lastThink();
} if (a < b);
Но даже разрешение только на return
операторов, вероятно, будет скользкой дорогой. Люди спросят: « вернуть x, если (a);
разрешено, так почему бы не что-то вроде doSomething () if (a);
?» а затем вы уже на спуске :)
Я знаю, что другим языкам это сходит с рук, но философия C # больше в том, чтобы сделать The One Right Way TM простым и иметь более одного способ сделать что-либо обычно избегают (хотя и с исключениями). Лично я считаю, что это работает очень хорошо, потому что я могу смотреть на чужой код и знать, что он почти в том же стиле, что и я.
Мне это некрасиво. Существующий синтаксис намного лучше.
if (x > y) return 3;
Да. Читается лучше. В Ruby это есть как часть синтаксиса - термин « модификаторы операторов »
irb(main):001:0> puts "Yay Ruby!" if 2 == 2
Yay Ruby!
=> nil
irb(main):002:0> puts "Yay Ruby!" if 2 == 3
=> nil
В заключение я должен подчеркнуть, что вам нужно «использовать это с осторожностью». Рубиновая идиома - использовать это для однострочных строк. Этим можно злоупотреблять - однако я полагаю, что это относится к сфере ответственной разработки - не ограничивайте лучших разработчиков, вводя ограничения для защиты слабых.
Лично мне нравятся языки, которые позволяют мне выбирать.
Тем не менее, если вы выполняете рефакторинг, а также переформатируете, вероятно, не имеет значения, какой стиль вы используете, потому что они будут одинаково удобочитаемы:
using System.Windows.Controls.Primitives;
...
var isContainersGenerated =
ProgenyList.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated;
if (!isContainersGenerated) return;
//alternatively
return if (!isContainersGenerated);
Люди читают от начала до конца. При анализе потока кода ограничения кратковременной памяти усложняют чтение постфиксных условий из-за необходимости дополнительного отката назад. Для коротких выражений это может не представлять проблемы, но для длинных выражений это вызовет значительные накладные расходы для пользователей, которые не владеют языком, на котором они читают.
Я думаю, Ларри Уолл был очень умен, когда ввел эту возможность в Perl. Идея заключается в том, что вы хотите поместить самую важную часть в начало, где ее легко увидеть. Если у вас есть короткое утверждение (т.е. не составное), вы можете поместить его перед if
/while
/etc. Если у вас длинный (т.е. составной) оператор, он помещается в скобки после условия.
При чтении кода возникает опасение, что вы думаете, что утверждение выполнится, а потом обнаруживаете, что оно может выполниться.
Например, если вы читаете "doSomething(x)", вы думаете: "Хорошо, это вызывает doSomething(x)", но затем вы читаете "if" после него и должны понять, что предыдущий вызов обусловлен оператором if.
Когда "if" стоит первым, вы сразу понимаете, что следующий код может произойти, и можете рассматривать его как таковой.
Мы склонны читать последовательно, поэтому читать и мысленно повторять "следующее может произойти" гораздо проще, чем читать и потом понимать, что все, что вы только что прочитали, нужно разобрать и оценить, не попадает ли это в область действия вашего нового оператора if.
На самом деле это похоже на множество вещей, это имеет смысл, когда вы используете его в ограниченном контексте (однострочник), и не имеет абсолютно никакого смысла, если вы используете его где-либо еще .
Проблема, конечно, в том, что было бы почти невозможно ограничить использование там, где это имеет смысл, и разрешать его использование там, где это не имеет смысла, просто странно.
Я знаю, что языки сценариев стремятся свести к минимуму количество строк кода, но когда вы говорите о скомпилированном языке, удобочитаемость является действительно ключевым моментом и настолько сильно, насколько это может оскорбить ваше восприятие. стиля, 4-строчная модель яснее, чем перевернутая if.
Согласен, что сбивает с толку, я никогда раньше не слышал об этой конструкции, поэтому считаю правильным использование then before if всегда должен содержать результат else, например
return (x > y) ? 3 : null;
else с использованием императивных конструкций вроде
return 3 if (x > y);
return 4 if (x = y);
return 5 if (x < y);
imho Это немного странно, потому что я понятия не имею, где это использовать ...