Порядок предметів у класах: Поля, Властивості, Конструктори, Методи


637

Чи існує офіційна інструкція C # щодо порядку впорядкування елементів з точки зору структури класів?

Чи йде:

  • Публічні поля
  • Приватні поля
  • Властивості
  • Конструктори
  • Методи
    ?

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

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

Якісь поради / пропозиції?


7
Насправді, щоб відповісти на фактичне запитання, ні, офіційного керівництва немає. StyleCop реалізує вказівки, розроблені для використання в одній конкретній групі в Microsoft. Це не є офіційним керівництвом і може навіть не бути рівномірним серед груп у Microsoft.
Джон Сондерс

2
Один простий трюк - побачити метадані якогось складного класу в .net (F12 в VS). Ви дізнаєтесь, як її замовили принаймні для членів publicта protectedчленів.
nawfal

19
Це питання не ґрунтується на думці, оскільки воно запитує, чи існує офіційний настанов Або є керівництво, або немає!
Саймон МenКензі

2
@nawfal Я розумію, що це старий коментар, мені подобається трюк, який ви згадали, але варто згадати, що він не з’явиться privateабо internalчлени (я вважаю). Гарний спосіб бачення publicі protected, проте. Ми можемо бачити джерело .NET Framework класів, тут referencesource.microsoft.com теж
Адам Plocher

Відповіді:


949

Відповідно до Документації Правил StyleCop замовлення здійснюється наступним чином.

У класі, структурі чи інтерфейсі: (SA1201 та SA1203)

  • Постійні поля
  • Поля
  • Конструктори
  • Фіналізатори (деструктори)
  • Делегати
  • Події
  • Перелічує
  • Інтерфейси ( реалізація інтерфейсу )
  • Властивості
  • Індексатори
  • Методи
  • Конструкції
  • Заняття

У кожній з цих груп упорядковуйте доступ: (SA1202)

  • громадські
  • внутрішній
  • захищений внутрішній
  • захищені
  • приватний

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

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

У межах кожної із статичних / нестатичних груп полів впорядковуйте лише за допомогою читання, а потім не лише для читання: (SA1214 та SA1215)

  • лише для читання
  • нечитання

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

  • публічні статичні методи
  • публічні методи
  • внутрішні статичні методи
  • внутрішні методи
  • захищені внутрішні статичні методи
  • захищені внутрішні методи
  • захищені статичні методи
  • захищені методи
  • приватні статичні методи
  • приватні методи

У документації зазначається, що якщо призначений порядок не підходить - скажімо, реалізується кілька інтерфейсів, а методи та властивості інтерфейсу повинні бути згруповані разом - тоді використовуйте частковий клас, щоб групувати пов'язані методи та властивості разом.


31
Хочу подякувати за докладені зусилля на цій посаді. Я намагаюся зробити речі StyleCop стандартними (навіть якщо просто бути послідовними та полегшити пошук речей), і це цінно.
Кенні Манн

47
Особисто мені здається, що впорядкування статичних методів дратує. Я бачу аргумент для статичних загальнодоступних методів, які приходять першими, але я зазвичай хочу приватні статичні методи після членів. Зрештою, вони комунальні служби.
Джонатан Райт

18
Мені сподобалась порада про частковий клас
Кіт Сірмонс

10
Просто примітка про часткові заняття. З огляду на те, що за час компіляції всі партії збираються в один тип, я завжди намагаюся забезпечити вагому причину для створення цих додаткових накладних витрат. Основна причина часткових класів полягає в розширенні автоматичного генерування вихідного коду або при роботі над великими проектами, щоб дозволити декільком розробникам працювати над одним класом, але окремими файлами.
Нема

4
@ FrançoisWahl Чи накладні витрати пов'язані з компілятором, що поєднує часткові класи в один тип, такий великий?
dav_i

38

Замість групування за видимістю або за типом елемента (поле, властивість, метод тощо), як щодо групування за функціональністю?


3
Якщо "сортування" за рекомендаціями StyleCop - це свого роду функціонал. Є вагома причина, чому одні методи є державними, а інші - приватними. Код справді легше читати: Якщо відкриваю .cs-файл класу, я одразу бачу публічні методи, «важливіші», ніж приватні (для хлопця, який використовує цей клас)
hfrmobile

75
Якщо у вашому класі так багато методів, властивостей тощо, що вам потрібно згрупувати їх за розділами, можливо, це ознака того, що клас робить занадто багато?
Райан Лунді

10
Навіть якщо клас невеликий, чи не було б сенсу групувати публічні методи з відповідними приватними методами, які називаються лише цим публічним методом?
Маркус Мейєр

11
+1, якщо публічний метод Foo () викликає захищений / приватний InternalFoo (), тоді другий метод краще бути прямо під DoFoo () у джерелі, а не десь далі серед інших захищених / приватних методів.
Андерс Форсгрен

60
групування за функціональністю називається класом
MrDosu

26

Це старе, але все ще дуже актуальне питання, тому я додам це: що перше, що ви шукаєте, коли відкриєте файл класу, який ви можете чи не могли прочитати раніше? Поля? Властивості? З досвіду я зрозумів, що майже незмінно ходжу на полювання на конструкторів, бо найголовніше, що потрібно зрозуміти, - як цей об’єкт побудований.

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

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

Смішно, скільки різниці має такий переупорядкування. Це нагадує мені про те, як usingвикористовувались замовлення операторів - спочатку з просторами імен системи. Команда "Організувати впорядкування" Visual Studio використовувала це замовлення. Тепер usings просто впорядковані в алфавітному порядку, без спеціального звернення до системних просторів імен. Результат просто відчуває себе простішим та чистішим.


2
Ініціалізація / побудова класів, на мій погляд, вивернута. Поля ініціалізуються перед запуском явних конструкторів, тому подальше продовження вашого аргументу по суті введення членів у порядок їх використання / створення, ініціалізовані поля були б раніше, ніж явно оголошені конструкторами. Ініціалізовані статичні поля та статичні конструктори роблять це ще цікавішим.
Девід Калп

1
Насправді, порядок, який вони, як правило, шукають люди, поняття літературного програмування, що код спочатку повинен бути зрозумілим людям.
яскравий

1
Слід зазначити , що первинні конструкторами були видалені з планів на C # 6: stackoverflow.com/a/26915809/5085211
Фугледе

4
9 разів з 10 я шукаю публічний інтерфейс, саме тому я ставлю всіх публічних членів спочатку, за ними внутрішні, за ними захищені, і нарешті приватні члени.
Метт Девіс

15

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

використовуючи заяви

Простір імен

Клас

Приватні члени

Громадські властивості

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

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

Приватні методи


Саме так я і роблю. За винятком між класом і приватними членами, у мене є якісь - або загальнодоступні константи і перерахування т.д.
deegee

Так, я вважаю за краще зберігати публічну власність після приватних методів. Інші люди вважають за краще ставити конструктор перед загальнодоступними властивостями ... але в голові я віддаю перевагу цінностям / конструкторам / поведінці в такому порядку. Тоді "значення" діляться на константи / privateMembers / властивості тощо. Зазвичай я не використовую регіони, за винятком деяких великих моделей перегляду ... ну, WPF-образні моделі є начебто особливими, і в цьому випадку я зазвичай ставлю резервні приватні поля безпосередньо перед кожною публічною власністю. У цьому випадку набір приватного поля плюс публічний член - це той самий підрозділ
zameb

15

Я рекомендую використовувати стандарти кодування від IDesign або ті, які вказані на веб-сайті Бреда Абрама . Це найкращі два, що я знайшов.

Бред сказав би ...

Учасники класів повинні бути за алфавітом і згруповані в розділи (Поля, Конструктори, Властивості, Події, Методи, Реалізація приватного інтерфейсу, Вкладені типи)


3
Схоже, це посилання просто призводить до домашньої сторінки IDesign в наші дні. Здається, стандарти кодування приховані за посиланням для завантаження електронною поштою #justsaying
Ліам

Настанови повинні мати обґрунтування. Обґрунтуванням цього є: 1. щоб ви зрозуміли, 2. щоб ви могли застосовувати судження щодо прикордонних, тонких, неоднозначних, непередбачених чи суперечливих випадків, 3. щоб ви могли скоригуватися, коли змінилися умови, а деякі правила не застосовуються.
Пабло H

6

Як було сказано раніше, на мові C # немає нічого, що диктує макет, я особисто використовую регіони, і я роблю щось подібне для середнього класу.

public class myClass
{
#region Private Members

#endregion
#region Public Properties

#endregion

#region Constructors

#endregion
#region Public Methods

#endregion
}

Для мене це все одно має сенс


19
Тут є (тільки для інформації) , що StyleCop дійсно не рекомендуємо використовувати регіони (SA1124 DoNotUseRegions)
Gerwald


1
@zwcloud Звичайно, у файлі з 5538 рядками потрібні регіони, але це не означає, що ви повинні використовувати регіони у звичайних файлах.
Ghost4Man

1
@Gerwald: Я думаю, що StyleCop призначений лише для людей, які використовують StyleCop. Це один із багатьох стандартів
zameb

1
@zameb: Я б сказав, що правила StyleCop - це одне з найпоширеніших вказівок кодування для C #. Під час кодування на будь-яких мовах я завжди намагаюся знайти найпоширеніший набір правил кодування та дотримуватися їх.
Гервальд

5

Від StyleCop

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

Оскільки StyleCop є частиною процесу збирання MS, ви можете розглядати це як фактичний стандарт


Цікаво. Чи використовуєте ви StyleCop регулярно?
mmcdole

Для одного проекту так, тому що він звикає знову і знову виконувати деякі контракти з МС. Це дуже дратує посмішку
мінет

1
Використання StyleCop протягом тривалого часу та, якщо використання цих рекомендацій, робить код по-справжньому легким для читання: Якщо відкрити .cs-файл класу, я одразу бачу публічні методи, які є "важливішими", ніж приватні. Публіка - це "інтерфейси" класу, що він пропонує і що можна перевірити (віддайте перевагу TDD та Test-First)
hfrmobile

1
Згідно з StyleCop, публічні поля повинні пройти перед приватними полями stylecop.com/docs/SA1202.html
Michael Freidgeim

1
Що ви маєте на увазі під "StyleCop - частина процесу складання MS"? Чи використовує Microsoft StyleCop для всього свого коду?
Ріко Сутер

5

Зазвичай я намагаюся слідувати наступній схемі:

  • статичні члени (зазвичай мають інший контекст, повинні бути безпечними для потоків тощо)
  • члени екземпляра

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

  • оператори (завжди статичні)
  • поля (ініціалізовані перед конструкторами)
  • конструктори
  • деструктор ( традиція наслідувати конструкторів )
  • властивості
  • методи
  • події

Потім члени сортуються за видимістю (від менш видимих ​​до більш видимих):

  • приватний
  • внутрішній
  • внутрішньо захищений
  • захищені
  • громадські

Порядок не є догмою: прості класи легше читати, однак складніші класи потребують групування, що залежить від контексту.


5

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

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, і якщо хтось може дати мені вагому причину, чому я повинен розмістити деталі реалізації типу перед його інтерфейсом, я готовий змінити. В даний час я сильно віддаю перевагу останнім членам приватних членів.

Примітка. Я не використовую публічні чи захищені поля.


3
Домовились. Мені дуже цікаво, чи поняття перших приватних членів не є переходом від C днів, коли змінні потрібно було оголосити першими. Я майже завжди хочу спершу бачити публічний інтерфейс, а не внутрішній клас.
Метт Девіс

1
Це насправді має багато сенсу. Б'юсь об заклад, що це призупинення від C.
Aluan Haddad

Однією з найбільших діток може бути властивості IMO. Коли у Ґеттера / сетера є логіка, про яку ви не знали, це набагато більше шансів укусити, ніж побічні ефекти в методах (які ви, природно, очікуєте, що вони є). Тому я віддаю перевагу властивостям поряд зі своїми полями вгорі. , тож коли я вперше дивлюсь на клас, бачу готчу. Якщо, коли я читаю метод, я як правило переходжу / переходжу негайно до методу все одно
Райан Ліч


3

Єдині рекомендації щодо кодування, які я бачив для цього, - це розміщення полів у верхній частині визначення класу.

я схильний ставити конструктори поруч.

мій загальний коментар буде, що ви повинні дотримуватися одного класу на файл, і якщо клас достатньо великий, що організація властивостей проти методів викликає велике занепокоєння, наскільки великий клас і чи варто вам все-таки рефакторинг? це представляє численні проблеми?


3
і як тільки вам потрібні регіони ... ви втратили.
Гаміш Сміт

3

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

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


3

Я тримаю це максимально просто (як мінімум для мене)

Перерахування
Декларації
Конструктори
Перекриває
Методи
Властивості
Обробник подій


2

Звичайно, в мові немає нічого, що б це не примусило. Я схильний групувати речі за видимістю (загальнодоступними, потім захищеними, потім приватними) і використовую # регіони функціонально групувати пов’язані речі, незалежно від того, чи це властивість, метод чи інше. Способи побудови (чи то фактичні електродвигуни, чи статичні заводські функції) зазвичай знаходяться вгорі, оскільки це перше, про що клієнти повинні знати.


Я також використовую регіони, щоб розділити їх за видимістю, і маючи регіональний макет коду, це мене чесно. rauchy.net/regionerate
Забутий

Я не бачу проблем із використанням #regions, проте я часто виявляю, що як тільки я спокушаюсь помістити в якийсь регіон, це спонукає мене розглянути питання про розділення моїх класів.
mikecamimo

2

Я знаю, що це старе, але моє замовлення таке:

в порядку публічного, захищеного, приватного, внутрішнього, абстрактного

  • Константи
  • Статичні змінні
  • Поля
  • Події
  • Конструктор (и)
  • Методи
  • Властивості
  • Делегати

Я також люблю виписувати такі властивості (замість скороченого підходу)

// 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; }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.