Должны ли папки в решении соответствовать пространству имен?

129

Должны ли папки в решении соответствовать пространству имен?

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

Название проекта и пространство имен: MyCompany.Project.Section.

В этом проекте есть несколько папок, соответствующих разделу пространства имен:

  • Папка Vehiclesимеет классы в MyCompany.Project.Section.Vehiclesпространстве имен
  • Папка Clothingимеет классы в MyCompany.Project.Section.Clothingпространстве имен
  • и т.п.

Внутри этого же проекта есть еще одна мошенническая папка

  • Папка BusinessObjectsимеет классы в MyCompany.Project.Sectionпространстве имен

Есть несколько таких случаев, когда папки создаются для «удобства организации».

У меня вопрос: какой стандарт? В библиотеках классов папки обычно соответствуют структуре пространства имен или это смешанный пакет?

Мариус Бансила
источник
9
Примечание: ReSharper будет жаловаться, если пространства имен не соответствуют иерархии папок.
Фред,

Ответы:

77

Также обратите внимание, что если вы используете встроенные шаблоны для добавления классов в папку, они по умолчанию будут помещены в пространство имен, которое отражает иерархию папок.

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

Мы следуем следующим правилам:

  • Имя проекта / сборки такое же, как и у корневого пространства имен, за исключением окончания .dll.
  • Единственным исключением из приведенного выше правила является проект с окончанием .Core, без .Core
  • Папки равны пространствам имен
  • Один тип для каждого файла (класс, структура, перечисление, делегат и т. Д.) Позволяет легко найти нужный файл
Лассе В. Карлсен
источник
1
+1 за «Единственное исключение из приведенного выше правила - проект с окончанием .Core, только .Core удален» . У меня есть MyProject.Core.dllсборка и все классы начинаются с MyProject.Core. Удаление .Coreсуффикса имеет гораздо больший смысл.
Луис Дамим
2
Еще одно исключение, которое я мог бы добавить, - это исключения. Исключения уже имеют суффикс «Исключение», поэтому дополнительное пространство имен является избыточным. Также может возникнуть беспорядок, если в части пространства имен есть слово Exception (может привести к путанице в System.Exception). Однако организация их по папкам весьма полезна.
phillipwei
55

Нет.

Я пробовал оба метода на малых и больших проектах, как с одним (мной), так и с командой разработчиков.

Я обнаружил, что самым простым и продуктивным путем было создание единого пространства имен для каждого проекта, и все классы входили в это пространство имен. Затем вы можете поместить файлы классов в любые папки проекта, которые захотите. Нет никаких проблем с добавлением операторов using вверху файлов постоянно, так как существует только одно пространство имен.

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

Возьмем, к примеру, это предупреждение FxCop:

CA1020: Избегайте пространств имен с несколькими типами.
Причина: пространство имен, отличное от глобального пространства имен, содержит менее пяти типов https://msdn.microsoft.com/en-gb/library/ms182130.aspx

Это предупреждение поощряет сброс новых файлов в общую папку Project.General или даже в корень проекта до тех пор, пока у вас не будет четырех аналогичных классов для обоснования создания новой папки. Произойдет ли это когда-нибудь?

Поиск файлов

В принятом ответе говорится: «Классы будет легче найти, и это само по себе должно быть достаточно вескими причинами».

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

В любом случае, хотя вы не можете определить, в какой папке находится файл класса из пространства имен, вы можете найти его, используя «Перейти к определению» или окно проводника поискового решения в Visual Studio. На мой взгляд, это не такая уж большая проблема. Я не трачу даже 0,1% времени разработки на поиск файлов, чтобы оправдать оптимизацию.

Конфликты имен

Конечно, создание нескольких пространств имен позволяет проекту иметь два класса с одинаковым именем. Но действительно ли это хорошо? Может быть, проще просто запретить это? Разрешение двух классов с одинаковым именем создает более сложную ситуацию, когда 90% времени все работает определенным образом, а затем вы внезапно обнаруживаете, что у вас особый случай. Допустим, у вас есть два класса Rectangle, определенные в отдельных пространствах имен:

  • класс Project1.Image.Rectangle
  • класс Project1.Window.Rectangle

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

var rectangle = new Project1.Window.Rectangle();

Или возитесь с каким-нибудь неприятным оператором using:

using Rectangle = Project1.Window.Rectangle;

С единым пространством имен в вашем проекте вы вынуждены придумывать разные, и я бы сказал, более описательные имена, подобные этому:

  • класс Project1.ImageRectangle
  • класс Project1.WindowRectangle

И использование везде одинаково, вам не нужно иметь дело с особым случаем, когда файл использует оба типа.

используя заявления

using Project1.General;  
using Project1.Image;  
using Project1.Window;  
using Project1.Window.Controls;  
using Project1.Shapes;  
using Project1.Input;  
using Project1.Data;  

против

using Project1;

Легкость отсутствия необходимости постоянно добавлять пространства имен при написании кода. На самом деле это не то время, которое требуется, это перерыв в выполнении и простое заполнение файлов множеством операторов using - для чего? Стоит ли оно того?

Изменение структуры папок проекта

Если папки сопоставлены с пространствами имен, то путь к папке проекта жестко запрограммирован в каждый исходный файл. Это означает, что любое переименование или перемещение файла или папки в проекте требует изменения фактического содержимого файла. И объявление пространства имен файлов в этой папке, и операторы using в целом ряде других файлов, которые ссылаются на классы в этой папке. Хотя сами изменения тривиальны с инструментами, обычно это приводит к большой фиксации, состоящей из множества файлов, классы которых даже не изменились.

С помощью единого пространства имен в проекте вы можете изменять структуру папок проекта, как хотите, без изменения самих исходных файлов.

Visual Studio автоматически сопоставляет пространство имен нового файла с папкой проекта, в которой он создан.

К сожалению, я считаю, что проблем с исправлением пространства имен меньше, чем хлопот с ними. Также у меня появилась привычка копировать и вставлять существующий файл, а не использовать Add-> New.

Intellisense и обозреватель объектов

На мой взгляд, самым большим преимуществом использования нескольких пространств имен в больших проектах является дополнительная организация при просмотре классов в любом инструменте, который отображает классы в иерархии пространств имен. Даже документация. Очевидно, что наличие только одного пространства имен в проекте приводит к тому, что все классы отображаются в едином списке, а не разбиваются на категории. Однако лично меня никогда не ставили в тупик или откладывали из-за отсутствия этого, поэтому я не считаю это достаточно большим преимуществом, чтобы оправдать использование нескольких пространств имен.

Хотя, если бы я писал большую публичную библиотеку классов, я бы, вероятно, использовал несколько пространств имен в проекте, чтобы сборка выглядела аккуратно в инструментах и ​​документации.

Вейланд Ютани
источник
30
Честно говоря, это одно из самых кошмарных решений, о которых я слышал. Если вы работаете над небольшими проектами hello world, этот совет работает, но представьте, что у вас есть более 1000 файлов .cs. Это вызвало бы столько проблем, что я не знаю, с чего начать.
BentOnCoding
10
"но представьте, что у вас есть более 1000 файлов .cs". Я работал в проектах такого размера с одним пространством имен. Все хорошо. Как вы думаете, какая катастрофа случится?
Weyland Yutani
14
+1 за размышления. Я не думаю, что готов сокращать свои пространства имен до одного на проект, но после работы над большой структурой я изучаю возможность уменьшения количества пространств имен, чтобы уменьшить количество операторов using и облегчить обнаружение методов расширения. Думаю, этот ответ дает хорошую пищу для размышлений. Спасибо.
Ли Ганн
3
@WeylandYutani, я знаю, что опаздываю, но мне нужно упомянуть, что это предложение: you can find it by using Go To Definition or the search solution explorer box in Visual Studioне всегда верно. Попробуйте много наследования и интерфейсов ... удачи в поиске нужного файла.
Эммануэль М.
11
Это один из лучших советов, которые я видел. Пространства имен предназначены только для разрешения конфликтов, а не для организации классов. Используйте пространства имен только там, где есть смысл их использовать, например, там, где вы ожидаете конфликтов имен с другими проектами, которые могут использовать ваш проект, позволяя включать или исключать определенные пространства имен с помощью операторов using. Ужасно иметь проект с 3 или 4 или более часто используемыми пространствами имен, потому что это всегда приводит к смехотворному количеству операторов using, которые вам нужно добавлять, добавлять и добавлять и добавлять. Разбивайте свои проекты на части.
Трийнко 02
31

Я думаю, что стандарт в .NET - это попытаться сделать это, когда это возможно, но не создавать излишне глубокие структуры, просто чтобы придерживаться этого как жесткого правила. Ни один из моих проектов не следует правилу namespace == structure в 100% случаев, иногда просто лучше / лучше выйти из таких правил.

В Java у вас нет выбора. Я бы назвал это классическим случаем того, что работает в теории, против того, что работает на практике.

Карл Сегин
источник
1
Я бы сказал: «Делайте это, когда действительно хотите, чтобы что-то находилось в собственном пространстве имен». Это должно быть осознанное решение. Если ваши проекты должным образом изолированы, это должно быть одно пространство имен для каждого проекта. Если ваш класс находится в пространстве имен, он должен находиться в папке с этим пространством имен ИЛИ в расположении подпапки, которое по крайней мере так же специфично, как и пространство имен. Класс, такой как Car.Ford.Fusion (если Car.Ford - ваше единственное пространство имен), должен находиться в папке, такой как Car / Ford, ИЛИ глубже, например, Car / Ford / Sedans, чтобы папка была по крайней мере такой же конкретной, как пространство имен. Только не помещайте это в Car / Unrelated / Ford; это сбивает с толку.
Трийнко 02
25

@lassevk: Я согласен с этими правилами, и хочу добавить еще одно.

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

// ----- Foo.cs
partial class Foo
{
    // Foo implementation here
}

и

// ----- Foo.Bar.cs
partial class Foo
{
    class Bar
    {
        // Foo.Bar implementation here
    }
}
Джей Базузи
источник
5

Я бы сказал да.

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

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

Конечно, само собой разумеется, что следует быть консервативным в отношении того, насколько глубока иерархия папок / пространств имен xis.

Ishmaeel
источник
4

Да, они должны, иначе только приведет к путанице.

Дэн
источник
2

Какой стандарт?

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

В библиотеках классов папки обычно соответствуют структуре пространства имен или это смешанный пакет?

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

user1451111
источник