Ordine delle voci nelle classi: campi, proprietà, costruttori, metodi


637

Esiste una linea guida C # ufficiale per l'ordine degli articoli in termini di struttura della classe?

Va bene:

  • Campi pubblici
  • Campi privati
  • Proprietà
  • Costruttori
  • Metodi
    ?

Sono curioso di sapere se esiste una regola rigida sull'ordine degli articoli? Sono un po 'dappertutto. Voglio attenermi a uno standard particolare in modo da poterlo fare ovunque.

Il vero problema è che le mie proprietà più complesse finiscono per assomigliare molto ai metodi e si sentono fuori posto nella parte superiore davanti al costruttore.

Eventuali suggerimenti / suggerimenti?


7
In realtà, per rispondere alla domanda effettiva, no, non esiste una linea guida ufficiale. StyleCop implementa le linee guida sviluppate per l'uso all'interno di un particolare gruppo in Microsoft. Questa non è una linea guida ufficiale e potrebbe non essere uniforme tra i gruppi di Microsoft.
John Saunders,

2
Un trucco semplice è vedere i metadati di una classe complessa in .net (F12 in VS). Verrai a sapere come è ordinato almeno per i membri publice protected.
nawfal,

19
Questa domanda non è basata sull'opinione, in quanto si chiede se esiste una linea guida ufficiale. O c'è una linea guida o non c'è!
Simon MᶜKenzie,

2
@nawfal Mi rendo conto che questo è un vecchio commento, mi piace il trucco che hai citato, ma vale la pena ricordare che non mostrerà privateo internalmembri (credo). Bel modo di vedere publice protected, comunque. Possiamo vedere la fonte di classi .NET Framework, qui referencesource.microsoft.com anche
Adam Plocher

Risposte:


951

Secondo la Documentazione sulle regole di StyleCop, l'ordinamento è il seguente.

All'interno di una classe, struttura o interfaccia: (SA1201 e SA1203)

  • Campi costanti
  • campi
  • Costruttori
  • Finalizzatori (distruttori)
  • I delegati
  • eventi
  • Enums
  • Interfacce ( implementazioni dell'interfaccia )
  • Proprietà
  • indicizzatori
  • metodi
  • Structs
  • Classi

All'interno di ciascuno di questi gruppi ordina per accesso: (SA1202)

  • pubblico
  • interno
  • interno protetto
  • protetta
  • privato

All'interno di ciascuno dei gruppi di accesso, ordina per statico, quindi non statico: (SA1204)

  • statico
  • non statico

All'interno di ciascuno dei gruppi di campi statici / non statici, ordina per sola lettura, quindi non sola lettura: (SA1214 e SA1215)

  • sola lettura
  • non in sola lettura

Un elenco non srotolato è lungo 130 righe, quindi non lo srotolerò qui. La parte dei metodi srotolata è:

  • metodi statici pubblici
  • metodi pubblici
  • metodi statici interni
  • metodi interni
  • metodi statici interni protetti
  • metodi interni protetti
  • metodi statici protetti
  • metodi protetti
  • metodi statici privati
  • metodi privati

La documentazione osserva che se l'ordine prescritto non è adatto, ad esempio, vengono implementate più interfacce e i metodi e le proprietà dell'interfaccia devono essere raggruppati insieme, utilizzare una classe parziale per raggruppare i metodi e le proprietà correlati.


31
Vorrei ringraziarvi per l'impegno profuso in questo post. Sto provando a rendere le cose StyleCop uno standard (anche se solo per essere coerenti e rendere facile trovare le cose) e questo è prezioso.
Kenny Mann,

47
Personalmente, trovo fastidioso l'ordinamento di metodi statici. Vedo prima l'argomento dei metodi pubblici statici, ma normalmente desidero i metodi statici privati ​​dopo i membri. Sono utilità dopo tutto.
Jonathan Wright,

18
Mi è piaciuto il suggerimento parziale della classe
Keith Sirmons,

10
Solo una nota sulle lezioni parziali. Dato che durante il tempo di compilazione tutti i parziali sono compilati in un unico tipo, proverei sempre a garantire una buona ragione per creare quel sovraccarico aggiuntivo. Il motivo principale delle classi parziali è l'estensione del codice sorgente di generazione automatica o quando si lavora su progetti di grandi dimensioni per consentire a più sviluppatori di lavorare sulla stessa classe ma file separati.
No,

4
@ FrançoisWahl L'overhead è associato al compilatore che combina classi parziali in un singolo tipo così grande?
davi

38

Invece di raggruppare per visibilità o per tipo di elemento (campo, proprietà, metodo, ecc.), Che ne dici di raggruppare per funzionalità?


3
Se "si ordina" usando i consigli di StyleCop è una specie di funzionalità. C'è una buona ragione per cui alcuni metodi sono pubblici e altri sono privati. Il codice è davvero più leggibile: se apro il file .cs di una classe vedo immediatamente i metodi pubblici che sono "più importanti" di quelli privati ​​(per il tipo che sta usando quella classe)
hfrmobile

75
Se hai così tanti metodi, proprietà, ecc. Nella tua classe che devi raggrupparli per sezione, forse è un segno che la classe sta facendo troppo?
Ryan Lundy

10
Anche se la classe è piccola, non avrebbe senso raggruppare i metodi pubblici con i corrispondenti metodi privati ​​che vengono chiamati solo da questo metodo pubblico?
Markus Meyer,

11
+1 se il metodo pubblico Foo () chiama InternalFoo () protetto / privato, allora quel secondo metodo dovrebbe essere proprio sotto DoFoo () nella fonte, non da qualche parte più in basso tra gli altri metodi protetti / privati.
Anders Forsgren,

60
il raggruppamento per funzionalità si chiama classe
MrDosu,

26

Questa è una domanda vecchia ma ancora molto pertinente, quindi aggiungerò questa: qual è la prima cosa che cerchi quando apri un file di classe che potresti aver letto o meno? I campi? Proprietà? Mi sono reso conto per esperienza che quasi invariabilmente vado a caccia di costruttori, perché la cosa più semplice da capire è come è costruito questo oggetto.

Pertanto, ho iniziato a mettere i costruttori al primo posto nei file di classe e il risultato è stato psicologicamente molto positivo. La raccomandazione standard di mettere i costruttori dopo un sacco di altre cose sembra dissonante.

L'imminente caratteristica del costruttore principale in C # 6 fornisce la prova che il posto naturale per un costruttore è in cima a una classe - in effetti i costruttori primari sono specificati anche prima del controvento aperto.

È divertente quanta differenza fa un riordino come questo. Mi ricorda come usingvenivano ordinate le istruzioni, prima con gli spazi dei nomi di sistema. Il comando "Organizza gli usi" di Visual Studio ha utilizzato questo ordine. Ora usingi messaggi sono ordinati alfabeticamente, senza alcun trattamento speciale riservato agli spazi dei nomi di sistema. Il risultato è più semplice e pulito.


2
A mio avviso, l'inizializzazione / costruzione della classe è contorta. I campi vengono inizializzati prima dell'esecuzione dei costruttori espliciti, quindi andando oltre l'argomento di essenzialmente mettere i membri nell'ordine in cui vengono utilizzati / creati, i campi inizializzati sarebbero prima dei costruttori dichiarati esplicitamente. I campi statici inizializzati e i costruttori statici lo rendono ancora più interessante.
David Culp,

1
In realtà, l'ordine in cui tendono ad essere cercati dagli umani, l'idea della programmazione letteraria che il codice dovrebbe essere prima leggibile dagli umani.
luminoso

1
Si noti che i costruttori primari sono stati rimossi dai piani per C # 6: stackoverflow.com/a/26915809/5085211
Fuglede

4
9 volte su 10, sto cercando l'interfaccia pubblica, motivo per cui ho inserito prima tutti i membri pubblici, seguiti da quelli interni, seguiti da quelli protetti e infine da quelli privati.
Matt Davis,

15

Non conosco un linguaggio o uno standard industriale, ma tendo a mettere le cose in questo ordine con ogni sezione racchiusa in una #regione:

usando le dichiarazioni

Spazio dei nomi

Classe

Membri privati

Proprietà pubbliche

Costruttori

Metodi pubblici

Metodi privati


Questo è esattamente come lo faccio anche io. Tranne che tra i membri Class e Private, ho Costanti
Enum

Sì, preferisco mantenere le proprietà pubbliche dopo i metodi privati. Altre persone preferiscono mettere il costruttore davanti a proprietà pubbliche ... ma nella mia testa preferisco avere valori / costruttori / comportamenti, in questo ordine. Quindi "valori" viene diviso in costanti / privateMembers / proprietà e così. Di solito non uso le regioni, ad eccezione di alcuni grandi modelli di vista ... beh, i modelli di visualizzazione WPF sono un po 'speciali e, in questo caso, metto i campi privati ​​di supporto appena prima di ogni proprietà pubblica. In questo caso, il set di campo privato più il membro pubblico è la stessa unità
zameb

15

Consiglio di utilizzare gli standard di codifica di IDesign o quelli elencati sul sito Web di Brad Abram . Questi sono i due migliori che ho trovato.

Brad direbbe ...

I membri delle classi devono essere alfabetizzati e raggruppati in sezioni (campi, costruttori, proprietà, eventi, metodi, implementazioni dell'interfaccia privata, tipi nidificati)


3
Quel link sembra condurre solo alla home page di IDesign in questi giorni. Sembra che gli standard di codifica siano nascosti dietro un link per il download via e-mail in questi giorni #justsaying
Liam

Le linee guida dovrebbero avere una logica. La logica di ciò è: 1. in modo da capire, 2. in modo da poter applicare il giudizio su casi limite, sottili, ambigui, imprevisti o in conflitto, 3. in modo da poter regolare quando le condizioni cambiano e alcune linee guida non si applicano più.
Pablo H,

6

Come accennato in precedenza, non c'è nulla nel linguaggio C # che impone il layout, io personalmente uso le regioni e faccio qualcosa del genere per una classe media.

public class myClass
{
#region Private Members

#endregion
#region Public Properties

#endregion

#region Constructors

#endregion
#region Public Methods

#endregion
}

Per me ha comunque senso


19
Ecco per dire (solo per informazione) che stylecop raccomanda di non usare le regioni (SA1124 DoNotUseRegions)
Gerwald


1
@zwcloud Certo, in un file con 5538 righe, le regioni sono necessarie, ma ciò non significa che dovresti usare le regioni nei file normali.
Ghost4Man,

1
@ Gerwald: Penso che StyleCop sia solo per le persone che usano StyleCop. È uno dei tanti standard
zameb

1
@zameb: Direi che le regole di StyleCop sono una delle linee guida di codifica più comuni per C #. Quando codifico in qualsiasi lingua, cerco sempre di trovare la serie più comune di linee guida per la codifica e seguirle.
Gerwald,

5

Da StyleCop

campi privati, campi pubblici, costruttori, proprietà, metodi pubblici, metodi privati

Poiché StyleCop fa parte del processo di compilazione di MS, è possibile vederlo come standard di fatto


Interessante. Usi StyleCop regolarmente?
mmcdole,

Per un progetto sì, perché viene utilizzato di tanto in tanto per alcuni contratti di lavoro MS. È un sorriso
Blowdart il

1
L'uso di StyleCop per lungo tempo e se l'utilizzo di tali consigli rende il codice davvero più leggibile: se si apre il file .cs di una classe vedo immediatamente i metodi pubblici che sono "più importanti" di quelli privati. I pubblici sono le "interfacce" della classe cosa offre e cosa può essere testato (preferisce TDD e Test-First)
hfrmobile

1
Secondo StyleCop i campi pubblici dovrebbero precedere i campi privati stylecop.com/docs/SA1202.html
Michael Freidgeim,

1
Cosa intendi con "StyleCop fa parte del processo di compilazione di MS"? Microsoft utilizza StyleCop per tutto il suo codice?
Rico Suter,

5

Di solito provo a seguire il modello seguente:

  • membri statici (di solito hanno un altro contesto, devono essere thread-safe, ecc.)
  • membri di istanza

Ogni parte (statica e istanza) è composta dai seguenti tipi di membri:

  • operatori (sono sempre statici)
  • campi (inizializzati prima dei costruttori)
  • costruttori
  • distruttore ( è una tradizione seguire i costruttori )
  • proprietà
  • metodi
  • eventi

Quindi i membri vengono ordinati in base alla visibilità (da meno a più visibile):

  • privato
  • interno
  • interno protetto
  • protetta
  • pubblico

L'ordine non è un dogma: le classi semplici sono più facili da leggere, tuttavia, le classi più complesse richiedono un raggruppamento specifico per il contesto.


5

La mia preferenza è ordinare per tipo e quindi diminuire la visibilità come segue

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

So che questo viola Style Cop e se qualcuno può darmi una buona ragione per cui dovrei mettere i dettagli di implementazione di un tipo prima della sua interfaccia, sono disposto a cambiare. Al momento, ho una forte preferenza a mettere per ultimo i membri privati.

Nota: non utilizzo campi pubblici o protetti.


3
Concordato. Mi chiedo davvero se l'idea di mettere al primo posto i membri privati ​​non sia una sospensione dai giorni C in cui le variabili dovevano essere dichiarate per prime. Voglio quasi sempre vedere prima l'interfaccia pubblica, non gli interni di classe.
Matt Davis,

1
Questo in realtà ha molto senso. Scommetto che è un holdover da C.
Aluan Haddad,

Alcuni dei più grandi gotcha possono essere le proprietà IMO. Quando c'è una logica su un getter / setter di cui non eri a conoscenza, sarà molto più probabile che mordi gli effetti collaterali nei metodi (che naturalmente ti aspetti che siano) Pertanto, preferisco le proprietà accanto ai loro campi in alto , quindi quando guardo una lezione per la prima volta, vedo il gotcha in cima. Dove come quando leggo un metodo, normalmente navigo / salto immediatamente al metodo comunque
Ryan The Leach


3

le uniche linee guida per la codifica che ho visto suggerire per questo sono di mettere i campi in cima alla definizione della classe.

tendo a mettere i costruttori dopo.

il mio commento generale sarebbe che dovresti attenersi a una classe per file e se la classe è abbastanza grande da rendere problematica l'organizzazione delle proprietà rispetto ai metodi, quanto è grande la classe e dovresti comunque effettuare il refactoring? rappresenta molteplici preoccupazioni?


3
e una volta che hai bisogno di regioni ... hai perso.
Hamish Smith,

3

Preferisco mettere i campi privati ​​in alto insieme al / ai costruttore / i, quindi inserire successivamente i bit di interfaccia pubblica, quindi i bit di interfaccia privata.

Inoltre, se la definizione della tua classe è abbastanza lunga perché l'ordinamento degli articoli contenga molto, è probabilmente un odore di codice che indica che la tua classe è troppo voluminosa e complessa e dovresti eseguire il refactoring.


3

Lo mantengo il più semplice possibile (almeno per me)

Enumerazioni
Dichiarazioni
Costruttori
Sostituisce
metodi
Proprietà
Gestore eventi


2

Non c'è certamente nulla nella lingua che lo imponga in alcun modo. Tendo a raggruppare le cose in base alla visibilità (pubblica, quindi protetta, quindi privata) e utilizzo #regioni per raggruppare le cose correlate funzionalmente, indipendentemente dal fatto che si tratti di una proprietà, metodo o altro. I metodi di costruzione (che si tratti di agenti di manutenzione reali o di funzioni statiche di fabbrica) sono di solito in cima poiché sono la prima cosa che i clienti devono conoscere.


Uso anche le regioni per separare in base alla visibilità e avere un layout di codice Regionerate mi rende onesto. rauchy.net/regionerate
virgola dimenticato

Non vedo alcun problema con l'uso di #regions, tuttavia trovo spesso che non appena sono tentato di inserirmi in una regione, mi spinge a considerare di dividere le mie classi.
mikecamimo,

2

So che questo è vecchio ma il mio ordine è il seguente:

in ordine di pubblico, protetto, privato, interno, astratto

  • costanti
  • Variabili statiche
  • campi
  • eventi
  • Constructor (s)
  • metodi
  • Proprietà
  • I delegati

Mi piace anche scrivere proprietà come questa (invece dell'approccio abbreviato)

// 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; }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.