Несколько классов в одном файле .cs - хорошо или плохо? [закрыто]


30

Желательно ли создавать несколько классов в файле .cs или каждый файл .cs должен иметь отдельный класс?

Например:

public class Items
{
    public class Animal
    {
    }

    public class Person
    {
    }

    public class Object
    {
    }
}

Уклонение на минуту от того, что это плохой пример хорошей архитектуры, имеет ли запах кода более одного класса в файле .cs?

Ответы:


30

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

  • вы проектируете кластер классов (более распространенный в target-c), поэтому может быть целесообразно использовать частичный подход к классам
  • вам нужен enum, который используется только с открытым API родительского класса. В этом случае я предпочитаю объявить открытый enum внутри родительского класса, а не загрязнять мое пространство имен. Перечисление, являющееся «внутренним перечислением», эффективно приводит к тому, что оно четко определено.

Если вы зададите вопрос немного по-другому и спросите: «Должен ли я поместить каждый класс уровня пространства имен в отдельный файл», мой ответ будет «да».

При разработке классов мы соблюдаем принцип единой ответственности. Чтение кода становится намного проще, если его форма соответствует семантике, поэтому целесообразно разделять файлы по классам.

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

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


1
Я согласен, но опять же внутренние занятия очень редки в моем опыте. Чтобы быть справедливым, на самом деле не так уж много, что может оправдать внутренние классы, единственный известный мне случай - это IEnumerable классы, где вы на самом деле не относитесь к фактическому классу, пока вы можете его перечислять. Во всех остальных случаях каждый класс должен получить свой собственный файл. Если по какой-либо другой причине из-за проблем с контролем версий.
Homde

2
Я бы добавил, что внутренние классы должны быть редким исключением и почти никогда не должны быть публичными.
Джош

Yup учит меня тому, что я так быстр, что с внутренними классами все в порядке, однако вопрос о том, стоит ли вам использовать innerclasses, это другой вопрос :)
krystan honor

11

Честно говоря, не добавляйте в файл более одного корневого класса. На моей последней работе были файлы не только с несколькими классами, но и с несколькими пространствами имен, которые растянулись на несколько тысяч строк кода. Очень трудно пытаться следовать.

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

Физическое разделение файлов классов помогает (заметьте, не всем конец) порождать разделение проблем и более слабую связь.

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


3
О боже, это звучит ужасно.

Почему ты спрашиваешь? Кто-то отрицал вас, и вы хотите спросить, почему?

Подожди ... ты имел в виду небольшой анекдот про мою последнюю работу? Если так, то я неправильно понял и прошу прощения за такое.
Джесси С. Slicer

Согласитесь полностью. Я работаю над проектом, в котором большинство файлов имеют как минимум 4 класса на файл. А некоторые имеют до 22 классов + 1 интерфейс на файл.
L_7337 15.12.14

7

Если файлы очень сплоченные, например, если это альтернатива наличию нескольких очень коротких файлов с одинаковыми именами, то это может быть хорошей идеей.

Например, я считаю , что при использовании Fluent NHibernate это легче , если я держать Entityи EntityMapв одном файле, несмотря на то , что мои инструменты , возможно , придется сказать об этом.

В большинстве случаев это просто затрудняет поиск классов. Используйте с осторожностью и с осторожностью.


1
Специально для Fluent NHibernate я счел полезным хранить их не только в одном файле, но и в одном классе. Все мои сущности имеют вложенный класс с именем Map.
Джеймс Бенинджер

7

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

Конечно, вы можете обойти это, используя функции инструментов, таких как resharper, для перехода к типам, но 1 класс на файл (включая интерфейсы) действительно является основой любого стандарта кода, который я когда-либо видел, не только в .net, но и в java и c ++ и многие другие языки, те, которые не часто имеют проблемы с сопровождением, и вы найдете младших разработчиков, которым сложно понять код.

Почти все инструменты оптимизации кода скажут вам переместить классы в отдельный файл, так что для меня да, это запах кода, и его нужно нейтрализовать :)


3

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


-3

По сути, если вам нужно использовать этот класс только из «родительского» класса (с точки зрения области видимости), то обычно целесообразно определить его как вложенный класс.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.