Форматирование / отступ для операторов using (C #)

Когда дело доходит до операторов using в C # (не путать с using директивами, которые импортируют пространства имен), Visual Studio не делает отступ в однострочном коде, который следует за ним, если не используются фигурные скобки. Это типично для «вложенности» операторов с использованием, как показано в этом вопросе SO.

Меня сбивает с толку то, что последующие операторы после using не имеют отступа, в отличие от форматирования оператора if:

// non-indented using statement
using (var myResource = new SomeIDisposableResource())
myResource.Indent(false);

// indented if statement
if (something == true)
    IndentMe();

Есть ли причина не делать отступы или это просто предпочтение?

// indented using statement, but not the default VS formatting
using (var myResource = new SomeIDisposableResource())
    myResource.Indent();

РЕДАКТИРОВАТЬ:

Дальнейшее тестирование показывает, что я ошибался в некоторых аспектах форматирования VS. Если вы наберете оператор using:

using (var myResource = SomeIDisposableResource())

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

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

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


person JYelton    schedule 14.09.2010    source источник
comment
Я не понимаю. Можете ли вы показать примеры обоих стилей? Вопрос, с которым вы связались, показывает код с отступом ... с завитками ...   -  person R. Martinho Fernandes    schedule 14.09.2010
comment
@Martinho Fernandes: Добавлены примеры по запросу.   -  person JYelton    schedule 14.09.2010
comment
На моей машине работает нормально, отступы появляются, как только я печатаю ;. Однако я отменил настройки по умолчанию.   -  person Hans Passant    schedule 14.09.2010
comment
По умолчанию отступы. Даже если вы аккуратно удалите отступ, нажмите «Форматировать документ», чтобы его восстановить.   -  person Steven Sudit    schedule 14.09.2010
comment
Если вы настаиваете на пропуске фигурных скобок, я бы вставил оператор using и вызов myResource.Indent() в одной строке. Хотя в данном случае я предпочитаю брекеты. Хотя я не особо возражаю против if (something == true) IndentMe(); как однострочного.   -  person Brian    schedule 14.09.2010
comment
@ Брайан: Это вывод, а не аргумент. Я заплатил за аргумент. Аргумент объяснил бы, какой возможный риск существует при пропуске фигурных скобок при отступе оператора с заданной областью действия.   -  person Steven Sudit    schedule 14.09.2010
comment
@Steven: Кроме того, OP даже не спрашивает, использовать ли фигурные скобки или нет. Поэтому я написал это как комментарий, а не как ответ.   -  person Brian    schedule 14.09.2010
comment
@Steven Sudit: Ах, вы правы относительно автоматического отступа VS. Я должен пояснить, что это не так, когда следующий оператор - это еще один оператор using. Я этого не тестировал: я нажимаю Enter после оператора using, и курсор выравнивается. Как только точка с запятой завершает оператор, он делает отступ, как в моем третьем примере. Я изменю свой вопрос для точности, но, тем не менее, это полезное обсуждение. :)   -  person JYelton    schedule 15.09.2010
comment
Я должен с этим согласиться. Разумный человек все еще может сделать вывод, что мы должны использовать фигурные скобки, несмотря на это автоматическое форматирование, но давайте, по крайней мере, поймем, что там есть вопреки.   -  person Steven Sudit    schedule 15.09.2010
comment
@Brian: Да, я ответил только тогда, когда понял, что мне нужно показывать код.   -  person Steven Sudit    schedule 15.09.2010
comment
@Hans Passant: На самом деле я не закончил утверждение, пока не был озадачен тем фактом, что курсор еще не имел отступа. Смущает, но все же кажется хорошим вопросом-ответом по форматированию, поскольку оно относится к блокам using.   -  person JYelton    schedule 15.09.2010
comment
Итак, здесь нет настоящей проблемы, верно? Мне действительно не нравятся ответы на вопросы о карго-культуре. Могу ли я опубликовать свои?   -  person Hans Passant    schedule 15.09.2010
comment
@Hans: Я думаю, что существует широкое согласие в пользу отступов, особенно с учетом того, что это предусмотрено редактором. Я также думаю, что есть широкое несогласие с моей позицией против использования дополнительных скобок. Я считаю это примером менталитета карго-культа, раз уж вы об этом упомянули. Не стесняйтесь публиковать свой ответ по любому вопросу, конечно.   -  person Steven Sudit    schedule 15.09.2010


Ответы (5)


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

using (Resource1 res1 = new Resource1())
using (Resource2 res2 = new Resource2())
using (Resource3 res3 = new Resource3())
{
    // Do stuff with res1, res2 and res3
}

Но я бы всегда использовал фигурные скобки для самого внутреннего блока :)

person Jon Skeet    schedule 14.09.2010
comment
Хороший звонок, я забыл о нескольких операторах using, накладываемых друг на друга. - person kemiller2002; 14.09.2010
comment
Кажется, что стек операторов using противоречит моей модели зависимостей кода. Под этим я подразумеваю, что считаю код с отступом зависимым от предыдущего блока с одним отступом меньше. Вставка некоторого кода между операторами using могла бы показаться приемлемой, основываясь исключительно на форматировании, но если я не ошибаюсь, это нарушит связь между операторами. Полагаю, это лишь одно из редких исключений из правил? - person JYelton; 14.09.2010
comment
Если вы вставляете код между двумя строками, вероятно, вы смотрите на эти строки. - person recursive; 14.09.2010
comment
@JYelton: Да, это исключение - я все равно редко этим занимаюсь, если честно, но об этом полезно знать. По сути, я мысленно отношусь ко всем операторам using как к их блоку. - person Jon Skeet; 14.09.2010
comment
Если мы собираемся разрешить штабелирование, то я не уверен, зачем нам скобки. - person Steven Sudit; 14.09.2010
comment
@Steven: Я фактически рассматриваю все операторы using как один ... Я все еще хочу, чтобы фигурные скобки отображали тело кода, который должен быть выполнен. - person Jon Skeet; 14.09.2010
comment
Причина, по которой я использовал фигурные скобки для такого рода вещей в C ++, заключалась в том, что было слишком легко иметь два оператора с отступом, поэтому казалось, что оба будут в блоке. В C #, использующем VS в качестве редактора, я не могу сделать это случайно или даже намеренно. Он исправляет мою ошибку! Это устраняет всякую мотивацию использовать брекеты. - person Steven Sudit; 14.09.2010
comment
Я разместил свой комментарий как ответ, чтобы показать образцы. Не стесняйтесь голосовать против. :-) - person Steven Sudit; 14.09.2010
comment
@recursive: О, вы правы, мне не нужно вставлять код между ними, но я вижу случай, когда кто-то может попытаться сделать это по ошибке. Я просто хотел утвердиться в этом вопросе. :) - person JYelton; 15.09.2010

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

using(var t = new t())
{
   t.Foo();
}
person kemiller2002    schedule 14.09.2010
comment
Даже для одиночных строк? Я предполагаю, что фигурные скобки просто заставляют VS делать отступ в соответствии с вашими предпочтениями? - person JYelton; 14.09.2010
comment
Да я даже для одиночных строк ставил. Это предпочтение, но я сталкивался со слишком многими ситуациями, когда кто-то случайно комментировал или удалял что-то, а оператор if расширяет его контроль за пределы того, где он должен. Иногда это сильная головная боль, которая требует нескольких часов отладки. Я следую четко сформулированному принципу: «Лучше перестраховаться, чем сожалеть». - person kemiller2002; 14.09.2010
comment
Кевин, были ли какие-либо из этих ситуаций в C # в отличие от C ++ или C? - person Steven Sudit; 14.09.2010
comment
@JYelton: имейте в виду, что VS будет отступать независимо от фигурных скобок. - person Steven Sudit; 14.09.2010
comment
@ Стивен, вообще-то да. Когда у меня такое случалось на C #, это обычно случается, потому что код изначально плохой. Это сбивает с толку, а иногда и делается плохо. Долгое время я никогда не думал, что это будет иметь такое большое значение для такого языка, как C # (по сравнению с C ++, C), который намного легче понять. А потом я увидел код C #, где это произошло. Я был невероятно разочарован, когда понял, что это проблема. - person kemiller2002; 14.09.2010
comment
@Kevin: Вы форматируете документ в процессе проверки? - person Steven Sudit; 14.09.2010
comment
С командой, в которой я сейчас участвую, да, мы делаем. Это было в другом проекте, где не было процесса проверки кода или реальных стандартов (на самом деле никто не хотел смотреть на этот код больше, чем это было необходимо). - person kemiller2002; 15.09.2010
comment
@Kevin: Я так и подумал. Когда у вас нет стандартов и процесса проверки, ничего не работает, потому что ничего не навязывается. - person Steven Sudit; 15.09.2010
comment
@Steven Sudit: Мне не удалось закончить написанное мной заявление точкой с запятой, чтобы убедиться, что в нем автоматически будет отступ. Я работал с положением курсора после нажатия клавиши ВВОД. В среде IDE поведение оператора using отличается от оператора if. Я изменил вопрос, чтобы отразить это. Очевидно, мне нужно убедиться, что я разрешил автоформатирование делать свою работу, прежде чем я что-то предполагаю! :) - person JYelton; 15.09.2010
comment
@JYelton: Вы правы: с if он отступает, как только вы нажимаете Enter. Я предполагаю, что причина, по которой он этого не делает для using, как раз в том, чтобы вы могли сложить их, как это сделал Джон. - person Steven Sudit; 15.09.2010

Простое исправление: всегда используйте явные блоки, даже для отдельных строк. Тогда Visual Studio выполнит правильный отступ, и в качестве бонуса ваш код станет более удобным в сопровождении!

person Randolpho    schedule 14.09.2010
comment
Вы имеете в виду более удобное в обслуживании, потому что фигурные скобки влияют на область видимости переменных? - person JYelton; 14.09.2010
comment
@JYelton, не совсем так. Более удобен в обслуживании, потому что, если вы позже захотите добавить туда строку или удалить ее для отладки или чего-то еще, фигурные скобки уже есть, и вы не рискуете забыть их и потратить часы на отладку. - person R. Martinho Fernandes; 14.09.2010
comment
@ Мартиньо Фернандес: У меня бывали такие ситуации; определенно хорошая причина всегда использовать брекеты. - person JYelton; 14.09.2010
comment
Их невозможно забыть, если вы не используете Блокнот или что-то в этом роде. Редактор VS предотвращает эту ошибку. - person Steven Sudit; 14.09.2010

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

person monkeymindllc    schedule 14.09.2010
comment
Действительно? Он сослужил мне хорошую службу с тех пор, как впервые появился C #. Почему вы сказали, что это не применимо? - person monkeymindllc; 15.09.2010

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

Вот как бы я его отформатировал:

using (Resource1 res1 = new Resource1())
using (Resource2 res2 = new Resource2())
using (Resource3 res3 = new Resource3())
  DoStuffWithResources(res1, res2, res3);

Если бы я заменил DoStuffWithResources несколькими операторами, я бы использовал фигурные скобки. Однако мой редактор не позволяет мне совершить следующую ошибку:

using (Resource1 res1 = new Resource1())
using (Resource2 res2 = new Resource2())
using (Resource3 res3 = new Resource3())
  DoStuffWithResources(res1, res2, res3);
  DoOtherStuffWithResources(res1, res2, res3);

При попытке ввести выше сразу получаю:

using (Resource1 res1 = new Resource1())
using (Resource2 res2 = new Resource2())
using (Resource3 res3 = new Resource3())
  DoStuffWithResources(res1, res2, res3);
DoOtherStuffWithResources(res1, res2, res3);

Совет профессионала: голос против не является контраргументом, поэтому, если у вас его нет, вам не следует голосовать.

person Steven Sudit    schedule 14.09.2010
comment
Мой аргумент в пользу использования скобок не из-за того, что я могу сделать, это следующий человек, которому я не доверяю. Это очень похоже на езду по заснеженной дороге зимой - я знаю, что могу позаботиться о себе, это все, что за рулем, пугают меня до чертиков. Если указать на точку, вы поймете, что вторая не имеет отступа - но как насчет младшего, которого приглашают для работы с дефектами? - person Joseph Ferris; 14.09.2010
comment
Следующий человек также использует редактор VS, поэтому то же самое предотвращает случайное создание этого второго блока кода им. Если вы работаете в обычном магазине, код будет рассмотрен перед выпуском или запуском в производство. В рамках проверки кода я всегда форматирую документ, чтобы ничего не изменилось. - person Steven Sudit; 14.09.2010
comment
@Steven, код будет пересматриваться? Если бы! Если бы только LOB видел такие дела так же ясно, как программисты. - person Anthony Pegram; 14.09.2010
comment
@Anthony: Это нормально, если вы проголосовали против - вы можете ошибаться. Все, о чем я прошу, это чтобы люди предлагали контраргумент, а не большой палец. Ваш аргумент, похоже, состоит в том, что некоторые магазины не проводят обзоры кода. К сожалению, вы правы в том, что они существуют. Однако вы правы и в том, что они за это страдают. Нет особого смысла говорить о преимуществах одного форматирования над другим, если, в конце концов, вы можете избежать наказания за убийство. - person Steven Sudit; 14.09.2010
comment
Оказалось, что я проголосовал против, но не хотел. Но что касается код-ревью, я работаю в команде довольно крупной финансовой компании. LOB платит за улучшения. Мы (имея в виду ворчунов) согласны с тем, что проверка кода была бы хорошей. Было бы замечательно провести рефакторинг неприлично длинных методов. (И я имею в виду непристойно долго.) Это было бы намного лучше для бизнес-класса в долгосрочной перспективе. Их не волнует долгосрочная перспектива, их волнует следующий выпуск. Но не обращайте на меня внимания, я сейчас просто выплеснусь. - person Anthony Pegram; 14.09.2010
comment
@Anthony: Мы все были там. Некоторые из нас там сейчас, остальные рано или поздно будут там снова. Удалите воздух, если необходимо; это немного лучше, чем взорваться, хотя и далеко не так хорошо, как найти лучшую работу. :-) - person Steven Sudit; 14.09.2010
comment
@ joseph.ferris: Я ответил на ваш комментарий, но забыл поставить перед ним префикс. - person Steven Sudit; 14.09.2010