Порядок предметов в классах: поля, свойства, конструкторы, методы

Существуют ли официальные правила C# для заказа предметов с точки зрения структуры классов?

Это идет:

  • Публичные поля
  • Частные поля
  • свойства
  • Конструкторы
  • методы
    ?

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

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

Любые советы / предложения?

16 ответов

Решение

В соответствии с документацией правил StyleCop порядок размещения следующий.

Внутри класса, структуры или интерфейса: (SA1201 и SA1203)

  • Постоянные поля
  • поля
  • Конструкторы
  • Финализаторы (Деструкторы)
  • Делегаты
  • События
  • Перечисления
  • Интерфейсы (реализации интерфейса)
  • свойства
  • индексаторы
  • методы
  • Структуры
  • Классы

Внутри каждой из этих групп порядок по доступу: (SA1202)

  • общественности
  • внутренний
  • защищенный внутренний
  • защищенный
  • частный

Внутри каждой из групп доступа упорядочение по статическому, а затем нестатическому: (SA1204)

  • статический
  • нестатическая

Внутри каждой из статических / нестатических групп полей упорядочьте только для чтения, затем не только для чтения: (SA1214 и SA1215)

  • только для чтения
  • без чтения

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

  • публичные статические методы
  • публичные методы
  • внутренние статические методы
  • внутренние методы
  • защищенные внутренние статические методы
  • защищенные внутренние методы
  • защищенные статические методы
  • защищенные методы
  • частные статические методы
  • частные методы

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

Вместо того чтобы группировать по видимости или по типу элемента (поле, свойство, метод и т. Д.), Как насчет группировки по функциональности?

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

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

Предстоящая функция первичного конструктора в C# 6 обеспечивает доказательство того, что естественное место для конструктора находится на самом верху класса - на самом деле первичные конструкторы указываются даже перед открытой фигурной скобкой.

Забавно, как много меняет такое изменение порядка. Это напоминает мне о том, как using операторы должны были быть упорядочены - сначала с пространствами имен System. Команда Visual Studio "Упорядочить использование" использовала этот порядок. Сейчас usingОни просто упорядочены в алфавитном порядке, без особой обработки для пространств имен System. Результат становится проще и чище.

Я не знаю ни языка, ни отраслевого стандарта, но я склоняюсь к тому, чтобы упорядочить каждый раздел, заключенный в #region:

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

Пространство имен

Учебный класс

Частные участники

Публичные свойства

Конструкторы

Публичные методы

Частные методы

Я бы порекомендовал использовать стандарты кодирования от IDesign или те, которые перечислены на сайте Брэда Абрама. Это лучшие два, которые я нашел.

Бред сказал бы...

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

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

public methods
public events
public properties

protected methods
protected events
protected properties

private methods
private events
private properties
private fields

public delegates
public interfaces
public classes
public structs

protected delegates
protected interfaces
protected classes
protected structs

private delegates
private interfaces
private classes
private structs

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

Примечание: я не использую открытые или защищенные поля.

Как упоминалось ранее, в языке C# нет ничего, что определяло бы макет, я лично использую регионы и делаю что-то подобное для среднего класса.

public class myClass
{
#region Private Members

#endregion
#region Public Properties

#endregion

#region Constructors

#endregion
#region Public Methods

#endregion
}

В любом случае это имеет смысл для меня

Обычно я стараюсь следовать следующей схеме:

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

Каждая часть (статическая и экземплярная) состоит из следующих типов элементов:

  • операторы (всегда статичны)
  • поля (инициализируются перед конструкторами)
  • конструкторы
  • деструктор (это традиция следовать за конструкторами)
  • свойства
  • методы
  • События

Затем элементы сортируются по видимости (от меньшего к более заметному):

  • частный
  • внутренний
  • внутренняя защита
  • защищенный
  • общественности

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

От StyleCop

частные поля, открытые поля, конструкторы, свойства, открытые методы, частные методы

Поскольку StyleCop является частью процесса сборки MS, вы можете рассматривать это как стандарт де-факто

Самое близкое, что вы можете найти, это "Рекомендации по проектированию, управляемый код и.NET Framework" ( http://blogs.msdn.com/brada/articles/361363.aspx) Брэда Абрамса.

Многие стандарты изложены здесь. Соответствующий раздел - 2,8, я думаю.

Я знаю, что это старый, но мой заказ выглядит следующим образом:

в порядке публичного, охраняемого, частного, внутреннего, абстрактного

  • Константы
  • Статические переменные
  • поля
  • События
  • Конструктор (ы)
  • методы
  • свойства
  • Делегаты

Мне также нравится выписывать такие свойства (вместо сокращенного подхода)

// Some where in the fields section
private int someVariable;

// I also refrain from
// declaring variables outside of the constructor

// and some where in the properties section I do
public int SomeVariable
{
    get { return someVariable; }
    set { someVariable = value; }
}

Я держу это настолько просто насколько возможно (для меня по крайней мере)

Перечисления
Объявления
Конструкторы
Переопределение
методы
свойства
Обработчик события

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

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

Я реструктурировал принятый ответ относительно того, что я считаю лучшим макетом:

Внутри класса, структуры или интерфейса:

  • Поля констант
  • Поля только для чтения
  • Поля
  • События
  • Характеристики
  • Индексаторы
  • Конструкторы
  • Финализаторы (деструкторы)
  • Интерфейсы (реализации интерфейса)
  • Методы
  • Классы
  • Структуры
  • перечисления
  • Делегаты

Внутри каждой из этих групп в порядке доступа:

  • публичный
  • внутренний
  • защищенный внутренний
  • защищенный
  • частный

В каждой из групп доступа упорядочите статические, а затем нестатические:

  • статический
  • нестатический

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

Единственное руководство по кодированию, которое я видел, предложило для этого, это поместить поля в верхнюю часть определения класса.

Я склонен ставить конструкторов дальше.

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

Конечно, в языке нет ничего, что могло бы навязать это. Я склонен группировать вещи по видимости (общедоступный, затем защищенный, затем частный) и использовать #regions для функциональной группировки связанных вещей, независимо от того, является ли это свойство, метод или что-то еще. Методы конструирования (будь то фактические ctors или статические фабричные функции) обычно находятся на самом верху, поскольку они - первое, что нужно знать клиентам.

Другие вопросы по тегам