Сегодня видел исходник, в котором присутствовала постоянная болезнь вкладывать скобочки друг в друга. Это просто ужасно. Мало того, что текст кода получился размашистым, так наглядность и читабельность ухудшилась. Может это я просто не привык читать такой код, но мне пришлось поднапрячься, чтобы сообразить, что там происходит.
Вот я образно накидал фигню, которую я видел:
foreach (MyMegaObject o in objects) { if (o != null) { foreach (Object1 n in o.GetNames()) { if (s != null) { if (s != " Something ") { Действия } } } } }
На мой взгляд это ужас как страшно. Главная проблема в том, что автор думает оператором "не равно". Когда пишете код, не нужно думать отрицаниями, думайте утверждениями и постоянно утверждайте. Например, если переменную "o" написать утверждением, то можно исправить код следующим образом:
if (o == null) continue;
Это уже избавление от лишних скобок. Вторая проблема - автор боиться объединять несколько проверок. Возможно он думает, что если первая не сработает, то вторая будет выполняться в любом случае. Да, есть такие языки, которые всегда проверяют все, но компилятор C# и .NET достаточно интеллектуальны, чтобы отменять проверку, если первая накрылась медным тазом. Например, вы можете без проблем написать следующий код:
if ((s == null) || (s.Value == " Something ")) continue;
Автор исходника побоялся написать это скорей всего потому, что если переменная s будет равна нулю, то вторая проверка вызовит исключение. Это так, но только если она будет проверяться, но она проверяться НЕ БУДЕТ. .NET проверяет все последовательно и если одна из проверок накрывается, то все останавливается. Поэтому объединять можно, глвное писать в правильной последовательности. Например, следующий код сгенерирует ошибку:
if ((s.Value == " Something ") || (s == null)) continue;
В этом случае, если s == null, то будет сгенерировано исключение, потому что первым будет проверяться (s.Value == " Something ").
Итак, тот страшный скобочный код мог быть переписан так:
foreach (MyMegaObject o in objects) { if (o == null) continue; foreach (object1 n in o.GetNames()) { if ((s == null) || (s.Value == " Something ") continue; Действия } }
На мой глазастый взгляд это на много красивее.
Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку пока еще никто не лайкал и ты можешь быть первым
рефакторинг батюшка :) тоже планирую заняться такими вещами, а то столько ужасного кода накопилось за несколько лет
Михаил, в книге, которую я сейчас читаю, от издательства APress, везде такой код. Как лучше оформлять? Я только начал учиться. :)
Каждый оформляет так, как ему удобно, я же описал то, что на мой взгляд лучше и нагляднее. В принципе, если ты будешь постоянно писать не равно (!=), то это не будет ошибкой, просто на мой взгляд не красиво. Когда слишком много скобок начинаешь в них путаться.
Михаил, а я наприме в С-подобных языках сделал для себя правилом отделать скобкой на отдельной строке namespace'ы, классы, методы, всё остальное (циклы, условия и т.д. - скобку ставить на той же строке. Код получается компактнее)
У нас на работе тоже так оформляют. Но когда я пишу дома, я использую VS, которая автоматом по умолчанию (в приципе, можно изменить) переносит скобку на отдельную строку. Когда скобка на той же строке, то код действительно компактнее, но тут вопрос не компактности, а читабельности кода. В данном случае, для меня оба варианта вполне читабельны.
Михаил, при всем уважении, но:
if ((s == null) || (s.Value == " Something ");
ИМХО, мусорный вариант. Как минимум, привязка к надежде на то, что в следующих версиях не поменяют логику работы, а в принципе - безолаберность программиста, который ввел потенциальный вылет ценой небольшого упрощения кода.
Это не меняется уже годами и скорей всего не поменяется, потому что все так пишут. Взгляни на заметку: http://flenov.info/blog.php?catid=746. Там явно ясходник MS и обрати внимание на эту конструкцию:
Я не писал в общем случае про .NET
Просто "я уверен" - аргумент, конечно, хороший =)
Это больше сила привычки, Double checked так сказать =)
Просто для интереса, как ты думаешь, зачем они захотят сменить логику? Я знаю, зачем они не будут менять:
1. производительность
2. обратная совместимость (представляешь, сколько им самим придется кода переворошить после такой шутки)
Не вижу ни одной причины менять и не только в С++. Есть языки (точно не помню, но читал где-то, что есть какой-то один, может несколько языков), где по стандарту по любасу проверяются все части. Но я считаю это глупостью.
Я не представляю варианта кроме явного бага в случае с .NET и данная конструкция будет работать.
Просто это стиль написания программ, и для меня он "грязный". Смысл делать потенциальное узкое место (пусть не .NET) мне непонятен. В запарке можно просто менять код и поменять местами операторы самому.
Ясно, но я не вижу смысла защищаться от багов .NET. Возможно, тут имеет даже смысл поднять спецификацию и посмотреть, как компилятор должен вести себя. Если он обязан проверять в такой последовательности, то не вижу ничего грязного. Хотя я не вижу в любом случае :)
RainBoy, менять никто ничиге не будет потому что есть && и &, || и |. И это не относится именно к .NET, это свойство языка C#. Такое поведение && и || сделано специально, чтобы ею пользовались. Подобное есть в C и C++.
if ((s == null) || (s.Value == " Something ");
Не придираюсь, ни в комем случае. Но не потеряна ли скопка в конце?
[Ради бога, не пропускай комментарий.]
Нет я пропущу, потому что я злой :). Да действительно там не хватает скобки. Я это заметил сразу после публикации, но впадлу было редактировать. Это хорошо, что ты можешь видеть такие ошибки на взгляд. Но во всех примерах есть одна еще более страшная ошибка - точка с запятой в конце:
if ((s.Value == " Something ") || (s == null));
continue;
В реальности это будет выполнено как:
if ((s.Value == " Something ") || (s == null))
; // пустой оператор
continue;
То есть если условие верно, то выполниться пустой оператор (ничего не выполниться), а вот после этого в любом случае будет выполнен continue
Скобочки это пустяк, если что на них всегда ругнеться компилятор.
А вот точка с запятой в конце трудноуловимая, и коварная ошибка, ведь как уже сказано, с точки зрения компилятора все будет верно..
Лучше бы такие ошибки мог выявлять на взгяд, чем банальные скобочки.. :)
Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.