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

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

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

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

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

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

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

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

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

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

Ответов (7)

Решение

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

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

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

  • Имя проекта / сборки такое же, как и у корневого пространства имен, за исключением окончания .dll.
  • Единственным исключением из приведенного выше правила является проект с окончанием .Core, без .Core
  • Папки равны пространствам имен
  • Один тип для каждого файла (класс, структура, перечисление, делегат и т. Д.) Позволяет легко найти нужный файл.

Нет.

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

Я обнаружил, что самым простым и продуктивным путем было создание единого пространства имен для каждого проекта, и все классы входили в это пространство имен. Затем вы можете поместить файлы классов в любые папки проекта, которые захотите. Нет никаких проблем с добавлением операторов 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 и обозреватель объектов

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

а также

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