Существующие стандарты кодирования в большом проекте C # включают правило, согласно которому все имена типов должны быть полностью квалифицированными, что запрещает использование директивы using. Итак, а не знакомые
using System.Collections.Generic;
.... other stuff ....
List<string> myList = new List<string>();
(Это, вероятно, не удивительно, что var
также запрещено.)
Я заканчиваю с:
System.Collections.Generic.List<string> myList = new System.Collections.Generic.List<string>();
Это увеличение на 134% при наборе текста, и ни одно из них не дает полезной информации. На мой взгляд, 100% увеличения - это шум (беспорядок), который на самом деле мешает пониманию.
За 30 с лишним лет программирования я видел такой стандарт, предложенный один или два раза, но так и не реализованный. Логическое обоснование этого ускользает от меня. Человек, навязывающий стандарт, не глуп, и я не думаю, что он злой. Что оставляет заблуждение как единственную альтернативу, если я что-то упустил.
Вы когда-нибудь слышали о введении такого стандарта? Если так, то в чем причина? Можете ли вы вспомнить другие аргументы, кроме «это глупо» или «все используют using
», которые могут убедить этого человека снять этот запрет?
аргументация
Причины этого запрета были:
- Наводить указатель мыши на имя, чтобы получить полностью определенный тип, будет неудобно. Лучше всегда иметь полностью определенный тип, видимый все время.
- Фрагменты кода, отправленные по электронной почте, не имеют полностью определенного имени, и поэтому могут быть трудны для понимания.
- При просмотре или редактировании кода вне Visual Studio (например, Notepad ++) невозможно получить полное имя типа.
Я утверждаю, что все три случая редки, и что заставить всех платить цену за загроможденный и менее понятный код только для того, чтобы приспособиться к нескольким редким случаям, ошибочно.
Потенциальные проблемы конфликта пространства имен, которые, как я ожидал, будут главной проблемой, даже не упоминались. Это особенно удивительно, потому что у нас есть пространство имен MyCompany.MyProject.Core
, что является особенно плохой идеей. Я давно узнал, что именование чего-либо System
или Core
C # - это быстрый путь к безумию.
Как уже отмечали другие, конфликты пространства имен легко обрабатываются с помощью рефакторинга, псевдонимов пространства имен или частичной квалификации.
источник
Ответы:
Более широкий вопрос:
Да, я слышал об этом, и использование полностью определенных имен объектов предотвращает конфликты имен. Хотя они случаются редко, они могут быть чрезвычайно сложными для понимания.
Пример. Этот тип сценария, вероятно, лучше объяснить на примере.
Допустим, у нас есть два,
Lists<T>
принадлежащих к двум отдельным проектам.Когда мы используем полное имя объекта, становится ясно, какое из
List<T>
них используется. Эта ясность, очевидно, достигается ценой многословия.И вы можете спорить: «Подождите! Никто никогда не использовал бы два таких списка!» Вот где я укажу сценарий обслуживания.
Вы написали модуль
Foo
для своей корпорации, который использует одобренную, оптимизированную корпорациюList<T>
.Позже новый разработчик решает расширить работу, которую вы выполняете. Не зная о стандартах компании, они обновляют
using
блок:И вы можете видеть, как дела идут плохо в спешке.
Следует отметить, что вы можете иметь два проприетарных класса с одним и тем же именем, но в разных пространствах имен в одном проекте. Так что речь идет не только о столкновении с классами, поставляемыми в .NET Framework.
Реальность:
В настоящее время, это , вероятно , произойдет в большинстве проектов? Нет, не совсем. Но когда вы работаете над большим проектом с большим количеством входов, вы делаете все возможное, чтобы свести к минимуму вероятность того, что на вас взорвется.
Крупные проекты с несколькими участвующими командами являются особым видом зверя в мире приложений. Правила, которые кажутся необоснованными для других проектов, становятся более уместными из-за входных потоков в проект и вероятности того, что участники не прочитали руководящие принципы проекта.
Это также может произойти, когда два больших проекта объединены вместе. Если у обоих проектов были классы с одинаковыми именами, вы увидите столкновения, когда начнете ссылаться из одного проекта в другой. И проекты могут быть слишком большими для рефакторинга, или руководство не утвердит расходы для финансирования времени, потраченного на рефакторинг.
Альтернативы:
Хотя вы не спрашивали, стоит отметить, что это не лучшее решение проблемы. Не стоит создавать классы, которые будут сталкиваться без объявлений их пространств имен.
List<T>
в частности, его следует рассматривать как зарезервированное слово, а не как имя для ваших классов.Аналогично, отдельные пространства имен в проекте должны стремиться иметь уникальные имена классов. Необходимость попытаться вспомнить, с каким пространством имен
Foo()
вы работаете, - это ментальные накладные расходы, которых лучше избегать. Сказал по-другому: иметьMyCorp.Bar.Foo()
иMyCorp.Baz.Foo()
собирается сбить с толку ваших разработчиков и лучше избегать.Если ничего другого, вы можете использовать частичные пространства имен для устранения неоднозначности. Например, если вы абсолютно не можете переименовать один из
Foo()
классов, вы можете использовать их частичные пространства имен:Конкретные причины вашего текущего проекта:
Вы обновили свой вопрос, указав конкретные причины, по которым вы указали свой текущий проект в соответствии с этим стандартом. Давайте посмотрим на них и действительно отвлечемся по следу кролика.
«Громоздкий?» Нет Раздражает возможно. Перемещение нескольких унций пластика для перемещения экранной указки не является громоздким . Но я отвлекся.
Эта линия рассуждений больше похожа на сокрытие, чем на что-либо еще. Случайно, я бы предположил, что классы в приложении имеют слабые имена, и вы должны полагаться на пространство имен, чтобы собирать соответствующее количество семантической информации, окружающей имя класса.
Это недопустимое обоснование для полностью определенных имен классов, возможно, это правильное обоснование для использования частично определенных имен классов.
Эта (продолжение?) Аргументация усиливает мое подозрение, что классы в настоящее время плохо названы. Опять же, наличие плохих имен классов не является хорошим оправданием для требования, чтобы все использовали полное имя класса. Если имя класса трудно понять, есть намного больше ошибок, чем то, что могут исправить полные имена классов.
Из всех причин эта чуть не заставила меня выплюнуть напиток. Но я опять отвлекся.
Мне интересно, почему команда часто редактирует или просматривает код за пределами Visual Studio? И теперь мы смотрим на обоснование, которое довольно хорошо ортогонально тому, что должны предоставить пространства имен. Это аргумент, поддерживаемый инструментами, тогда как пространства имен служат для обеспечения организационной структуры кода.
Похоже, что ваш проект страдает от плохих соглашений об именах вместе с разработчиками, которые не пользуются преимуществами того, что инструмент может им предоставить. И вместо того, чтобы решить эти реальные проблемы, они пытаются нанести лейкопластырь на один из симптомов и требуют полностью квалифицированных имен классов. Я думаю, что это можно отнести к категории ошибочного подхода.
Принимая во внимание, что существуют плохо названные классы, и при условии, что вы не можете выполнить рефакторинг, правильный ответ - использовать Visual Studio IDE в полной мере. Возможно, рассмотрите возможность добавления в плагин, такой как пакет VS PowerTools. Затем, когда я смотрю,
AtrociouslyNamedClass()
я могу щелкнуть имя класса, нажать F12 и перейти непосредственно к определению класса, чтобы лучше понять, что он пытается сделать. Кроме того, я могу нажать Shift-F12, чтобы найти все места в коде, которые в настоящее время нуждаются в использованииAtrociouslyNamedClass()
.Что касается внешних проблем с инструментами, лучше всего просто остановить их. Не посылайте фрагменты по электронной почте взад и вперед, если они не сразу понимают, на что ссылаются. Не используйте другие инструменты вне Visual Studio, так как эти инструменты не обладают интеллектом вокруг кода, который нужен вашей команде. Notepad ++ - потрясающий инструмент, но он не предназначен для этой задачи.
Поэтому я согласен с вашей оценкой в отношении трех конкретных обоснований, которые вам были представлены. Тем не менее, я думаю, что вам сказали: «У нас есть основные проблемы в этом проекте, которые не могут / не будут решаться, и именно так мы их« исправили »». И это, очевидно, говорит о более глубоких проблемах в команде, которые могут служить для вас «красными флагами».
источник
usings
но это не похоже на то, что ваш проект квалифицируется как один из таких случаев.Я работал в одной компании, где у них было много классов с одинаковыми именами, но в разных библиотеках классов.
Например,
Вы можете сказать, что плохой дизайн, но вы знаете, как эти вещи развиваются органично, и какова альтернатива - переименовать все классы, чтобы они включали пространство имен? Главный рефакторинг всего?
В любом случае, было несколько мест, где проектам, которые ссылались на все эти разные библиотеки, требовалось использовать несколько версий класса.
С
using
прямо сверху, это было основной проблемой в заднице, ReSharper делал бы странные вещи, пытаясь заставить это работать, переписываяusing
директивы на лету, вы получали бы Customer-not-be-cast-as- Ошибки стиля клиента и не знаю, какой тип был правильным.Итак, имея хотя бы частичное пространство имен,
или же
значительно улучшил читабельность кода и сделал его явным, какой объект вы хотите.
Это не был стандарт кодирования, это не было полное пространство имен, и он не применялся ко всем классам в качестве стандарта.
источник
Нет ничего хорошего в том, чтобы быть слишком многословным или слишком коротким: нужно найти золотую середину в том, чтобы быть достаточно подробным, чтобы предотвратить тонкие ошибки, избегая при этом написания слишком большого количества кода.
В C # примером этого являются имена аргументов. Я несколько раз сталкивался с проблемой, когда я часами искал решение, в то время как более подробный стиль написания мог бы предотвратить эту ошибку. Проблема состоит в ошибке в порядке аргументов. Например, выглядит ли это правильно для вас?
На первый взгляд выглядит отлично, но есть ошибка. Подписи конструкторов исключений:
Заметили порядок аргументов?
Приняв более подробный стиль, в котором имя аргумента указывается каждый раз, когда метод принимает два или более аргумента одного типа , мы предотвращаем повторное возникновение ошибки, и поэтому:
очевидно, что писать дольше, но в результате отладка затрачивается меньше времени.
Вытесняя до крайности, можно заставить везде использовать именованные аргументы , в том числе в таких методах,
doSomething(int, string)
где нет способа смешать порядок параметров. Это, вероятно, нанесет вред проекту в долгосрочной перспективе, в результате чего будет гораздо больше кода без выгоды от предотвращения ошибки, описанной выше.В вашем случае, мотивация
using
правила «Нет » состоит в том, что оно должно усложнить использование неправильного типа, например «MyCompany.Something.List<T>
против»System.Collections.Generic.List<T>
.Лично я бы избегал такого правила, потому что, IMHO, стоимость сложного для чтения кода намного выше выгоды от слегка сниженного риска неправильного использования неправильного типа, но, по крайней мере, для этого правила есть веская причина.
источник
paramName
сInvokerParameterName
атрибутом и выдает предупреждение , если такой параметр не существует.SomeBusiness.Something.DoStuff(string name, string description)
? Ни один инструмент не достаточно умен, чтобы понять, что такое имя и описание.Пространства имен дают коду иерархическую структуру, допускающую более короткие имена.
Если вы разрешите ключевое слово "using", существует цепочка событий ...
(потому что оно включает в себя каждое пространство имен, которое они могут захотеть)
Поэтому, чтобы избежать риска, все начинают использовать действительно длинные имена:
Ситуация обостряется ...
Я видел, как это произошло, поэтому могу посочувствовать компаниям, которые запрещают «использование».
источник
using
- это ядерный вариант. Псевдонимы пространства имен и частичная квалификация являются предпочтительными.Проблема в
using
том, что он волшебным образом добавляет пространство имен без явного объявления. Это гораздо большая проблема для программиста по обслуживанию, который сталкивается с чем-то подобнымList<>
и не знаком с доменом, не знает, какоеusing
предложение ввело его.Аналогичная проблема возникает в Java, если кто-то пишет,
import Java.util.*;
а не,import Java.util.List;
например; последняя декларация документирует, какое имя было введено, так что когда этоList<>
происходит позже в источнике, его происхождение известно изimport
декларации.источник