Reihenfolge der Elemente in Klassen: Felder, Eigenschaften, Konstruktoren, Methoden

635

Gibt es eine offizielle C # -Richtlinie für die Reihenfolge der Elemente in Bezug auf die Klassenstruktur?

Geht es:

  • Öffentliche Felder
  • Private Felder
  • Eigenschaften
  • Konstruktoren
  • Methoden
    ?

Ich bin gespannt, ob es eine feste Regel für die Reihenfolge der Artikel gibt. Ich bin irgendwie überall. Ich möchte mich an einen bestimmten Standard halten, damit ich ihn überall machen kann.

Das eigentliche Problem ist, dass meine komplexeren Eigenschaften am Ende sehr nach Methoden aussehen und sich oben vor dem Konstruktor fehl am Platz anfühlen.

Irgendwelche Tipps / Vorschläge?

mmcdole
quelle
7
Um die eigentliche Frage zu beantworten, nein, es gibt keine offizielle Richtlinie. StyleCop implementiert die Richtlinien, die für die Verwendung innerhalb einer bestimmten Gruppe in Microsoft entwickelt wurden. Dies ist keine offizielle Richtlinie und möglicherweise nicht einmal einheitlich für Gruppen in Microsoft.
John Saunders
2
Ein einfacher Trick besteht darin, die Metadaten einer komplexen Klasse in .net (F12 in VS) anzuzeigen. Sie werden erfahren, wie es zumindest für die publicund protectedMitglieder bestellt ist.
Nawfal
19
Diese Frage basiert nicht auf Meinungen, da sie fragt, ob es eine offizielle Richtlinie gibt. Entweder gibt es eine Richtlinie oder es gibt keine!
Simon MᶜKenzie
2
@nawfal Mir ist klar, dass dies ein alter Kommentar ist. Ich mag den Trick, den Sie erwähnt haben, aber es ist erwähnenswert, dass er nicht angezeigt wird privateoder internalMitglieder (glaube ich). Schöne Sichtweise publicund protectedtrotzdem. Wir können die Quelle von .NET Framework - Klassen sehen, hier referencesource.microsoft.com zu
Adam Plocher

Antworten:

947

Gemäß der StyleCop-Regeldokumentation ist die Reihenfolge wie folgt.

Innerhalb einer Klasse, Struktur oder Schnittstelle: (SA1201 und SA1203)

  • Konstante Felder
  • Felder
  • Konstruktoren
  • Finalizer (Destruktoren)
  • Delegierte
  • Veranstaltungen
  • Aufzählungen
  • Schnittstellen ( Schnittstellenimplementierungen )
  • Eigenschaften
  • Indexer
  • Methoden
  • Strukturen
  • Klassen

Innerhalb jeder dieser Gruppen nach Zugriff sortieren: (SA1202)

  • Öffentlichkeit
  • intern
  • intern geschützt
  • geschützt
  • Privat

Innerhalb jeder der Zugriffsgruppen nach statisch und dann nicht statisch sortieren: (SA1204)

  • statisch
  • nicht statisch

Ordnen Sie innerhalb jeder der statischen / nicht statischen Feldgruppen schreibgeschützt und dann nicht schreibgeschützt: (SA1214 und SA1215)

  • schreibgeschützt
  • nicht schreibgeschützt

Eine abgewickelte Liste ist 130 Zeilen lang, daher werde ich sie hier nicht abrollen. Der entrollte Methodenteil ist:

  • öffentliche statische Methoden
  • öffentliche Methoden
  • interne statische Methoden
  • interne Methoden
  • geschützte interne statische Methoden
  • geschützte interne Methoden
  • geschützte statische Methoden
  • geschützte Methoden
  • private statische Methoden
  • private Methoden

In der Dokumentation wird darauf hingewiesen, dass, wenn die vorgeschriebene Reihenfolge nicht geeignet ist - beispielsweise mehrere Schnittstellen implementiert werden und die Schnittstellenmethoden und -eigenschaften zusammengefasst werden sollten -, eine Teilklasse verwendet wird, um die zugehörigen Methoden und Eigenschaften zusammenzufassen.

Jonathan Wright
quelle
31
Ich möchte mich bei Ihnen für die Mühe in diesem Beitrag bedanken. Ich versuche, StyleCop-Inhalte zu einem Standard zu machen (auch wenn dies nur konsistent ist und das Auffinden von Dingen erleichtert), und das ist wertvoll.
Kenny Mann
47
Persönlich finde ich die Reihenfolge der statischen Methoden ärgerlich. Ich kann das Argument für statische öffentliche Methoden als erstes sehen, aber normalerweise möchte ich private statische Methoden nach Mitgliedern. Sie sind schließlich Dienstprogramme.
Jonathan Wright
18
Ich mochte den
Teilklassentipp
10
Nur ein Hinweis zu Teilklassen. Da während der Kompilierungszeit alle Partials zu einem einzigen Typ kompiliert werden, würde ich immer versuchen, einen guten Grund für die Erstellung dieses zusätzlichen Overheads sicherzustellen. Der Hauptgrund für Teilklassen besteht darin, den automatisch generierten Quellcode oder bei der Arbeit an großen Projekten zu erweitern, damit mehrere Entwickler an derselben Klasse, aber an separaten Dateien arbeiten können.
Nein,
4
@ FrançoisWahl Ist der mit dem Compiler verbundene Overhead, der Teilklassen zu einem einzigen Typ kombiniert, so groß?
dav_i
37

Wie wäre es mit einer Gruppierung nach Funktionalität, anstatt nach Sichtbarkeit oder nach Elementtyp (Feld, Eigenschaft, Methode usw.) zu gruppieren?

Ryan Lundy
quelle
3
Wenn Sie anhand der StyleCop-Empfehlungen "sortieren", handelt es sich um eine Art Funktionalität. Es gibt einen guten Grund, warum einige Methoden öffentlich und andere privat sind. Der Code ist wirklich besser lesbar: Wenn ich die CS-Datei einer Klasse öffne, sehe ich sofort die öffentlichen Methoden, die "wichtiger" sind als die privaten (für den Typ, der diese Klasse verwendet)
hfrmobile
75
Wenn Ihre Klasse so viele Methoden, Eigenschaften usw. enthält, dass Sie sie nach Abschnitten gruppieren müssen, ist dies möglicherweise ein Zeichen dafür, dass die Klasse zu viel tut?
Ryan Lundy
10
Wäre es nicht sinnvoll, öffentliche Methoden mit ihren entsprechenden privaten Methoden zu gruppieren, die nur von dieser öffentlichen Methode aufgerufen werden, selbst wenn die Klasse klein ist?
Markus Meyer
11
+1 Wenn die öffentliche Methode Foo () ein geschütztes / privates InternalFoo () aufruft, befindet sich diese zweite Methode besser direkt unter DoFoo () in der Quelle und nicht weiter unten unter anderen geschützten / privaten Methoden.
Anders Forsgren
60
Die Gruppierung nach Funktionen wird als Klasse bezeichnet
MrDosu
25

Dies ist eine alte, aber immer noch sehr relevante Frage, daher füge ich Folgendes hinzu: Was ist das Erste, wonach Sie suchen, wenn Sie eine Klassendatei öffnen, die Sie möglicherweise zuvor gelesen haben oder nicht? Felder? Eigenschaften? Ich habe aus Erfahrung festgestellt, dass ich fast immer auf die Jagd nach den Konstruktoren gehe, denn das Grundlegendste, was ich verstehen muss, ist, wie dieses Objekt aufgebaut ist.

Daher habe ich begonnen, Konstruktoren in Klassendateien an die erste Stelle zu setzen, und das Ergebnis war psychologisch sehr positiv. Die Standardempfehlung, Konstruktoren nach einer Reihe anderer Dinge zu setzen, fühlt sich dissonant an.

Die bevorstehende Funktion für Primärkonstruktoren in C # 6 zeigt, dass der natürliche Platz für einen Konstruktor ganz oben in einer Klasse steht. Tatsächlich werden Primärkonstruktoren bereits vor der offenen Klammer angegeben.

Es ist lustig, wie viel Unterschied eine solche Nachbestellung macht. Es erinnert mich daran, wie usingAnweisungen früher bestellt wurden - zuerst mit den System-Namespaces. Der Befehl "Organisieren von Verwendungen" von Visual Studio verwendete diese Reihenfolge. Jetzt sind usings nur noch alphabetisch geordnet, ohne dass System-Namespaces speziell behandelt werden. Das Ergebnis fühlt sich einfach und sauber an.

hell
quelle
2
Die Initialisierung / Konstruktion von Klassen ist meiner Meinung nach kompliziert. Felder werden initialisiert, bevor explizite Konstruktoren ausgeführt werden. Wenn Sie also Ihr Argument weiterführen, Mitglieder im Wesentlichen in die Reihenfolge zu bringen, in der sie verwendet / erstellt werden, werden initialisierte Felder vor explizit deklarierten Konstruktoren angezeigt. Initialisierte statische Felder und statische Konstruktoren machen es noch interessanter.
David Culp
1
Tatsächlich ist die Reihenfolge, in der sie von Menschen gesucht werden, der Begriff der literarischen Programmierung, dass Code zuerst von Menschen gelesen werden sollte.
hell
1
Beachten Sie, dass primäre Konstruktoren aus den Plänen für C # 6 entfernt wurden: stackoverflow.com/a/26915809/5085211
fuglede
4
9 mal von 10 suche ich nach der öffentlichen Schnittstelle, weshalb ich alle öffentlichen Mitglieder an die erste Stelle stelle, gefolgt von internen, gefolgt von geschützten und schließlich von privaten Mitgliedern.
Matt Davis
15

Ich kenne keine Sprache oder keinen Industriestandard, aber ich neige dazu, die Dinge in diese Reihenfolge zu bringen, wobei jeder Abschnitt in eine # Region eingeschlossen ist:

Verwenden von Anweisungen

Namespace

Klasse

Private Mitglieder

Öffentliche Immobilien

Konstruktoren

Öffentliche Methoden

Private Methoden

Wayne
quelle
Genau so mache ich es auch. Außer zwischen Klassen- und Privatmitgliedern habe ich öffentliche Konstanten und Aufzählungen usw.
Deegee
Ja, ich bevorzuge es, öffentliche Immobilien nach privaten Methoden zu behalten. Andere Leute bevorzugen es, den Konstruktor vor öffentliche Objekte zu stellen ... aber in meinem Kopf bevorzuge ich es, Werte / Konstruktoren / Verhaltensweisen in dieser Reihenfolge zu haben. Dann wird "Werte" als Konstanten / privateMembers / Eigenschaften usw. geteilt. Normalerweise verwende ich keine Regionen, außer für einige große Ansichtsmodelle ... Nun, WPF-Ansichtsmodelle sind etwas Besonderes, und in diesem Fall setze ich normalerweise die privaten Hintergrundfelder direkt vor jede öffentliche Eigenschaft. In diesem Fall ist die Menge des privaten Feldes plus des öffentlichen Mitglieds dieselbe Einheit
zameb
15

Ich würde empfehlen, die Codierungsstandards von IDesign oder die auf der Website von Brad Abram aufgeführten zu verwenden . Das sind die besten zwei, die ich gefunden habe.

Brad würde sagen ...

Das Klassenmitglied sollte alphabetisch sortiert und in Abschnitte gruppiert sein (Felder, Konstruktoren, Eigenschaften, Ereignisse, Methoden, Implementierungen privater Schnittstellen, verschachtelte Typen).

Elijah Manor
quelle
3
Dieser Link scheint heutzutage nur zur IDesign-Homepage zu führen. Es scheint , die Coding - Standards sind hinter einem Emailed Download - Link versteckt in diesen Tagen #justsaying
Liam
Richtlinien sollten eine Begründung haben. Der Grund dafür ist: 1. damit Sie verstehen, 2. damit Sie Grenzfälle, subtile, mehrdeutige, unvorhergesehene oder widersprüchliche Fälle beurteilen können, 3. damit Sie sich anpassen können, wenn sich die Bedingungen ändern und einige Richtlinien nicht mehr gelten.
Pablo H
6

Wie bereits erwähnt, gibt es in der C # -Sprache nichts, was das Layout vorschreibt. Ich persönlich verwende Regionen und mache so etwas für eine durchschnittliche Klasse.

public class myClass
{
#region Private Members

#endregion
#region Public Properties

#endregion

#region Constructors

#endregion
#region Public Methods

#endregion
}

Es macht sowieso Sinn für mich

Mitchel Sellers
quelle
19
Hier ist zu sagen (nur zur Information), dass stylecop empfiehlt, keine Regionen zu verwenden (SA1124 DoNotUseRegions)
Gerwald
1
@zwcloud Sicher, in einer Datei mit 5538 Zeilen sind Regionen erforderlich, aber das bedeutet nicht, dass Sie Regionen in normalen Dateien verwenden sollten.
Ghost4Man
1
@ Gerwald: Ich denke, StyleCop ist nur für Leute, die StyleCop verwenden. Es ist einer von vielen Standards
Zameb
1
@zameb: Ich würde sagen, die StyleCop-Regeln sind eine der häufigsten Codierungsrichtlinien für C #. Wenn ich in einer beliebigen Sprache codiere, versuche ich immer, die gängigsten Codierungsrichtlinien zu finden und diese zu befolgen.
Gerwald
5

Von StyleCop

private Felder, öffentliche Felder, Konstruktoren, Eigenschaften, öffentliche Methoden, private Methoden

Da StyleCop Teil des MS-Erstellungsprozesses ist, können Sie dies als De-facto-Standard betrachten

Blasrohrpfeil
quelle
Interessant. Verwenden Sie StyleCop regelmäßig?
mmcdole
Für ein Projekt ja, weil es ab und zu für einige MS-Vertragsarbeiten verwendet wird. Es ist sehr nervig grinsen
Blowdart
1
Wenn Sie StyleCop für eine lange Zeit verwenden und diese Empfehlungen verwenden, ist der Code wirklich besser lesbar: Wenn Sie die CS-Datei einer Klasse öffnen, werden sofort die öffentlichen Methoden angezeigt, die "wichtiger" sind als die privaten. Die Öffentlichkeit ist die "Schnittstelle" der Klasse, was sie bietet und was getestet werden kann (bevorzugen TDD und Test-First)
hfrmobile
1
Laut StyleCop sollten öffentliche Felder vor privaten Feldern stehen. Stylecop.com/docs/SA1202.html
Michael Freidgeim
1
Was meinst du mit "StyleCop ist Teil des MS-Build-Prozesses"? Verwendet Microsoft StyleCop für den gesamten Code?
Rico Suter
5

Normalerweise versuche ich, dem nächsten Muster zu folgen:

  • statische Elemente (haben normalerweise einen anderen Kontext, müssen threadsicher sein usw.)
  • Instanzmitglieder

Jeder Teil (statisch und Instanz) besteht aus den folgenden Elementtypen:

  • Operatoren (sind immer statisch)
  • Felder (vor Konstruktoren initialisiert)
  • Konstruktoren
  • Destruktor ( ist eine Tradition, um den Konstrukteuren zu folgen )
  • Eigenschaften
  • Methoden
  • Veranstaltungen

Dann werden die Mitglieder nach Sichtbarkeit sortiert (von weniger zu mehr sichtbar):

  • Privat
  • intern
  • intern geschützt
  • geschützt
  • Öffentlichkeit

Die Reihenfolge ist kein Dogma: Einfache Klassen sind leichter zu lesen, komplexere Klassen benötigen jedoch eine kontextspezifische Gruppierung.

Michael Damatov
quelle
5

Ich bevorzuge es, nach Art zu bestellen und dann die Sichtbarkeit wie folgt zu verringern

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

Ich weiß, dass dies gegen Style Cop verstößt, und wenn mir jemand einen guten Grund geben kann, warum ich die Implementierungsdetails eines Typs vor dessen Schnittstelle stellen sollte, bin ich bereit, dies zu ändern. Gegenwärtig habe ich eine starke Präferenz dafür, private Mitglieder an die letzte Stelle zu setzen.

Hinweis: Ich verwende keine öffentlichen oder geschützten Felder.

Aluan Haddad
quelle
3
Einverstanden. Ich frage mich wirklich, ob der Gedanke, die privaten Mitglieder an die erste Stelle zu setzen, kein Überbleibsel aus den C-Tagen ist, in denen Variablen zuerst deklariert werden mussten. Ich möchte fast immer zuerst die öffentliche Oberfläche sehen, nicht die Interna der Klasse.
Matt Davis
1
Das macht eigentlich sehr viel Sinn. Ich wette, es ist ein Überbleibsel von C.
Aluan Haddad
Einige der größten Fallstricke können die IMO-Eigenschaften sein. Wenn es eine Logik für einen Getter / Setter gibt, von der Sie nichts gewusst haben, ist es viel wahrscheinlicher, dass sie beißt als Nebenwirkungen bei Methoden (von denen Sie natürlich erwarten, dass sie vorhanden sind). Daher bevorzuge ich Eigenschaften neben ihren Feldern oben Wenn ich mir also zum ersten Mal eine Klasse anschaue, sehe ich, dass die Gotcha oben ist. Wo wie beim Lesen einer Methode ich normalerweise sowieso
Ryan The Leach
4

Am nächsten finden Sie wahrscheinlich "Design Guidelines, Managed Code und .NET Framework" ( http://blogs.msdn.com/brada/articles/361363.aspx ) von Brad Abrams

Viele Standards werden hier beschrieben. Der relevante Abschnitt ist 2.8, denke ich.

Rory Becker
quelle
3

Die einzigen Codierungsrichtlinien, die ich dafür vorgeschlagen habe, sind Felder oben in der Klassendefinition.

Ich neige dazu, Konstruktoren als nächstes zu setzen.

Mein allgemeiner Kommentar wäre, dass Sie sich an eine Klasse pro Datei halten sollten. Wenn die Klasse groß genug ist, dass die Organisation von Eigenschaften im Vergleich zu Methoden ein großes Problem darstellt, wie groß ist die Klasse und sollten Sie sie trotzdem umgestalten? Stellt es mehrere Bedenken dar?

Hamish Smith
quelle
3
und wenn Sie Regionen brauchen ... haben Sie verloren.
Hamish Smith
3

Ich ziehe es vor, die privaten Felder zusammen mit den Konstruktoren oben zu platzieren und danach die öffentlichen Schnittstellenbits und dann die privaten Schnittstellenbits zu setzen.

Wenn Ihre Klassendefinition lang genug ist, damit die Reihenfolge der Elemente eine große Rolle spielt, ist dies wahrscheinlich ein Codegeruch, der darauf hinweist, dass Ihre Klasse zu umfangreich und komplex ist und Sie eine Umgestaltung vornehmen sollten.

Keil
quelle
3

Ich halte es so einfach wie möglich (zumindest für mich)

Aufzählungen
Erklärungen
Konstrukteurs
Überschreibungen
Methoden
Eigenschaften
Event - Handler

Klopfen
quelle
2

Es gibt sicherlich nichts in der Sprache, was es in irgendeiner Weise erzwingt. Ich neige dazu, Dinge nach Sichtbarkeit zu gruppieren (öffentlich, dann geschützt, dann privat) und #regions zu verwenden, um verwandte Dinge funktional zu gruppieren, unabhängig davon, ob es sich um eine Eigenschaft, eine Methode oder was auch immer handelt. Konstruktionsmethoden (ob tatsächliche ctors oder statische Factory-Funktionen) stehen normalerweise ganz oben, da sie das erste sind, über das Kunden Bescheid wissen müssen.

Jeff Kotula
quelle
Ich verwende Regionen, um sie auch nach Sichtbarkeit zu trennen, und ein Regionerate-Code-Layout hält mich ehrlich. rauchy.net/regionerate
Vergessenes Semikolon
Ich sehe kein Problem bei der Verwendung von #regions, aber ich stelle oft fest, dass ich, sobald ich versucht bin, eine Region einzurichten, überlege, meine Klassen aufzuteilen.
Mikecamimo
2

Ich weiß, dass dies alt ist, aber meine Bestellung lautet wie folgt:

in der Reihenfolge öffentlich, geschützt, privat, intern, abstrakt

  • Konstanten
  • Statische Variablen
  • Felder
  • Veranstaltungen
  • Konstruktor (en)
  • Methoden
  • Eigenschaften
  • Delegierte

Ich schreibe auch gerne Eigenschaften wie diese aus (anstelle des Kurzansatzes)

// 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; }
}

quelle