Warum empfiehlt StyleCop, Methoden- oder Eigenschaftsaufrufen mit "this" voranzustellen?

68

Ich habe versucht, die Richtlinien von StyleCop für ein Projekt zu befolgen, um festzustellen, ob der resultierende Code am Ende besser war. Die meisten Regeln sind vernünftig oder eine Ansichtssache zum Kodierungsstandard, aber es gibt eine Regel, die mich verwirrt, weil ich niemanden gesehen habe, der sie empfiehlt, und weil ich keinen klaren Vorteil dafür sehe:

SA1101: Der Aufruf von {Methoden- oder Eigenschaftsname} muss mit dem 'this' beginnen. Präfix, um anzuzeigen, dass das Element Mitglied der Klasse ist.

Auf der anderen Seite ist der Code auf diese Weise deutlich ausführlicher. Welche Vorteile bietet die Einhaltung dieser Regel? Folgt hier jemand dieser Regel?

Mathias
quelle
11
Beachten Sie, dass StyleCop für Ihre Anforderungen konfiguriert werden soll und die Standardeinstellungen möglicherweise nicht optimal sind. Nicht alle StyleCop-Regeln sind gleichermaßen vernünftig, und ich erinnere mich, dass es einige gab, die geradezu widersprüchlich waren und nicht erfüllt werden konnten, wenn beide aktiviert waren. Wenn Sie bereits einen Codierungsstil haben, der in diesem Aspekt für Sie _geeignet ist (z. B. Präfixfelder mit scheint beliebt zu sein), halten Sie sich daran und ändern Sie die StyleCop-Einstellungen entsprechend.
Pavel
9
Die Standardeinstellungen stellen jedoch einen Standard dar. Wenn Sie also Code haben möchten, der dem Standard entspricht, der von einem Körper außerhalb Ihres Teams erstellt wurde, passen Sie die Regeln nicht an.
JeremyWeir
8
@Pavel: Ich gehe davon aus, dass StyleCop mit den Standardregeln geliefert wird, denen Microsoft folgt, und ich würde glauben, dass diese Regeln eine Begründung haben. Bevor ich die Standardeinstellung ändere, möchte ich verstehen, warum sie so eingestellt wurde!
Mathias
2
@Mathias - Einige der Regeln, z. B. wo Ihre usingDeklarationen abgelegt werden sollen , werden von den Klassenvorlagen nicht einmal erfüllt. Ich bin mir nicht sicher, ob alle gesund sind.
Marc Gravell
1
@Mathias: Wenn ich mich an die Geschichte von StyleCop erinnere, wurde es ursprünglich nicht Microsoft-weit verwendet. Ich würde nicht davon ausgehen, dass die StyleCop-Regeln von Microsoft verwendet werden. Vor allem nicht das "das". Regel.
John Saunders

Antworten:

71

Es kann den Code auf einen Blick klarer machen. Wenn Sie verwenden this, ist es einfacher:

  • Unterscheiden Sie statische und Instanzmitglieder. (Und unterscheiden Sie Instanzmethoden von Delegaten.)
  • Unterscheiden Sie Instanzmitglieder von lokalen Variablen und Parametern (ohne Verwendung einer Namenskonvention).
Jeff Sternal
quelle
4
Einverstanden über die Klassenfelder im Vergleich zu lokalen Variablen. Die Notation _ oder m_ für Klassenfelder sieht für mich wie ein Archaismus aus, und diese Regel ist eine vernünftige Möglichkeit, sie zu ersetzen und gleichzeitig die Lesbarkeit zu gewährleisten.
Mathias
8
Sie können genau das Gleiche erreichen, indem Sie eindeutige Affixe für Elementvariablen (z. B. m_nameVersus name) und keine für lokale Variablen und Parametervariablen verwenden. Es ist jedoch eine Frage des Geschmacks.
David R Tribble
2
@Loadmaster - Ich möchte auch hinzufügen, dass bei Verwendung eines Affixes / Präfixes wie Unterstrich die Verwendung durch den Namen erzwungen wird, während Sie sich beim Schlüsselwort 'this' auf Tools wie StyleCop verlassen müssen, um die Verwendung zu erzwingen.
Jpierson
7
Wenn Sie thiszur Unterscheidung von Mitgliedern verwenden, verwenden Sie im Grunde genommen eine Namenskonvektion. Es ist also nicht besser, als _oder mit dem Präfix zu versehen m_. In der Tat ist es schlimmer, da für die Verwendung thismehr Zeichen erforderlich sind.
Sean
3
Visual Studio schlägt vor, das von stylecop vorgeschlagene "this" zu entfernen. Können sie sich nicht entscheiden?
Zahnrad
93

Ich folge dieser Anleitung nur dann wirklich, wenn ich mich in den Szenarien befinde, die Sie benötigen:

  • Es gibt eine tatsächliche Mehrdeutigkeit - hauptsächlich betrifft dies entweder Konstruktoren ( this.name = name;) oder Dinge wie Equals( return this.id == other.id;)
  • Sie möchten einen Verweis auf die aktuelle Instanz übergeben
  • Sie möchten eine Erweiterungsmethode für die aktuelle Instanz aufrufen

Davon abgesehen betrachte ich diese Unordnung. Also schalte ich die Regel aus.

Marc Gravell
quelle
2
Dies ist absolut die richtige Antwort. "Dies" überall in Ihrem Code zu haben, ist dumm und wird nirgendwo gelehrt.
Philip Vaughn
39

Ich denke, dieser Artikel erklärt es ein wenig

http://blogs.msdn.microsoft.com/sourceanalysis/archive/2008/05/25/a-difference-of-style.aspx

... ein brillanter junger Entwickler bei Microsoft (ok, ich war es) hat beschlossen, ein kleines Tool zu schreiben, mit dem Abweichungen vom C # -Stil in seinem Team festgestellt werden können. StyleCop wurde geboren. In den nächsten Jahren haben wir alle C # -Stilrichtlinien zusammengestellt, die wir von den verschiedenen Teams innerhalb von Microsoft finden konnten, und alle Best Practices ausgewählt, die diesen Stilen gemeinsam waren. Diese bildeten den ersten Satz von StyleCop-Regeln. Eine der frühesten Regeln, die sich aus dieser Anstrengung ergaben, war die Verwendung dieses Präfixes zum Aufrufen von Klassenmitgliedern und das Entfernen von Unterstrichpräfixen aus Feldnamen. Der C # -Stil war offiziell von seinem alten C ++ - Stamm getrennt.

JeremyWeir
quelle
1
Danke, schön die Insider-Geschichte zu haben!
Mathias
22
Danke für den Link. Es sagt mir, warum die StyleCop-Regeln größtenteils Mist sind - sie sind eine Reihe von Regeln von verstreuten Teams und kein einziges, gut durchdachtes Regelwerk, das untersucht wurde, um festzustellen, ob sie tatsächlich die besten für Teams von sind alle Fähigkeitsstufen.
John Saunders
Nun, im Jahr 2019 scheinen stylecop.analyzers einige ziemlich strenge Regeln zu haben, und ich lasse die meisten aktiviert; Nur wenige davon und das Verbot von #region sind wirklich fraglich. Ich hätte gerne eine bessere Anpassung und Abdeckung einiger anderer Dinge, z. B. der Zeilenlänge als Teil des Regelsatzes, aber zum größten Teil ist es großartig. Ich meine, ich bin nur hier, weil ich das Verdienst jeder Regel nachschaue.
Person27
4. November 2020, Verbindung ist unterbrochen.
spikey_richie
20
this.This 
this.Does 
this.Not 
this.Add 
this.Clarity 
this.Nor 
this.Does 
this.This 
this.Add 
this.Maintainability 
this.To 
this.Code

Die Verwendung von "this.", Wenn sie übermäßig verwendet wird oder eine erzwungene Stilanforderung ist, ist nichts anderes als eine Erfindung, die unter dem Deckmantel verwendet wird, dass es <1% der Entwickler gibt, die Code oder das, was sie tun, wirklich nicht verstehen und es machen schmerzhaft für 99%, die leicht lesbaren und wartbaren Code schreiben möchten.

Sobald Sie mit der Eingabe beginnen, listet Intellisence den verfügbaren Inhalt in dem Bereich auf, in dem Sie eingeben: "this". ist nicht erforderlich, um Klassenmitglieder freizulegen, und wenn Sie nicht völlig ahnungslos sind, wofür Sie codieren, sollten Sie in der Lage sein, den gewünschten Gegenstand leicht zu finden.

Auch wenn Sie völlig ahnungslos sind, verwenden Sie "dies". um anzugeben, was verfügbar ist, aber lassen Sie es nicht im Code. Es gibt auch eine Reihe von Add-Ons wie Resharper, die dazu beitragen, den Umfang klarer zu gestalten und den Inhalt von Objekten effizienter darzustellen. Es ist besser zu lernen, wie man die Ihnen zur Verfügung gestellten Werkzeuge verwendet, als eine schlechte Angewohnheit zu entwickeln, die von einer großen Anzahl Ihrer Mitarbeiter gehasst wird.

Entwickler, die den Umfang statischer, lokaler, klassenbezogener oder globaler Inhalte nicht von Natur aus verstehen, sollten sich nicht auf "Hinweise" verlassen, um den Umfang anzugeben. "diese." ist schlechter als die ungarische Notation, da zumindest die ungarische Notation eine Vorstellung von dem Typ hat, auf den sich die Variable bezieht, und einen gewissen Nutzen bringt. Ich würde lieber "_" oder "m" sehen, um Klassenfeldmitglieder zu bezeichnen, als "dies" zu sehen. überall.

Ich hatte noch nie ein Problem oder ein Problem mit einem anderen Entwickler, der wiederholt mit dem Codeumfang kämpft oder Code schreibt, der immer fehlerhaft ist, weil er "this" nicht verwendet. ausdrücklich. Es ist eine ungerechtfertigte Angst, dass "dies". verhindert zukünftige Codefehler und ist häufig das Argument, bei dem Unwissenheit geschätzt wird.

Codierer wachsen mit der Erfahrung, "dies". Es ist, als würde man jemanden bitten, als Erwachsener Stützräder auf sein Fahrrad zu setzen, weil er damit zuerst lernen musste, wie man Fahrrad fährt. Und Erwachsene könnten 1 von 1000 Mal von einem Fahrrad fallen, wenn sie darauf steigen, aber das ist kein Grund, sie zu zwingen, Stützräder zu verwenden.

"diese." sollte aus der Sprachdefinition für C # verbannt werden, gibt es leider nur einen Grund für die Verwendung, nämlich das Auflösen von Mehrdeutigkeiten, die auch durch bessere Code-Praktiken leicht gelöst werden könnten.

ChrisCW
quelle
1
gut ausgedrückt. Ich konnte mir keinen Fehler vorstellen, den wir in den letzten Jahren aufgrund des fehlenden "Dies" hatten. Schöner Vergleich mit den Stützrädern :)
Stefan Sieber
Gut ausgedrückt. Unnötige Unordnung für mich.
Kraeg
9

Beachten Sie, dass es dem Compiler egal ist, ob Sie Referenzen voranstellen thisoder nicht (es sei denn, es liegt eine Namenskollision mit einer lokalen Variablen und einem Feld vor oder Sie möchten eine Erweiterungsmethode für die aktuelle Instanz aufrufen.)

Es liegt an deinem Stil. Persönlich entferne ich this.aus dem Code, da ich denke, dass dies das Signal-Rausch-Verhältnis verringert.

Nur weil Microsoft diesen Stil intern verwendet, müssen Sie dies nicht tun. StyleCop scheint ein MS-internes Tool zu sein, das an die Öffentlichkeit gebracht wurde. Ich bin alle dafür, die Microsoft-Konventionen in Bezug auf öffentliche Dinge einzuhalten, wie zum Beispiel:

  • Typnamen befinden sich in PascalCase
  • Parameternamen sind in camelCase
  • Schnittstellen sollte der Buchstabe I vorangestellt werden
  • Verwenden Sie einzelne Namen für Aufzählungen, außer wenn es sich um [Flags] handelt.

... aber was im privaten Bereich Ihres Codes passiert, ist privat. Tun Sie, worauf sich Ihr Team einigt.

Konsistenz ist ebenfalls wichtig. Es reduziert die kognitive Belastung beim Lesen von Code, insbesondere wenn der Codestil Ihren Erwartungen entspricht. Aber selbst wenn es sich um einen fremden Codierungsstil handelt, dauert es nicht lange, bis er sich daran gewöhnt hat, wenn er konsistent ist. Verwenden Sie Tools wie ReSharper und StyleCop, um die Konsistenz dort sicherzustellen, wo Sie es für wichtig halten.

Die Verwendung von .NET Reflector deutet darauf hin, dass Microsoft die StyleCop-Codierungsstandards in der BCL ohnehin nicht so gut einhält.

Drew Noakes
quelle
2
.NET Reflector zeigt Ihnen den geschriebenen Quellcode nicht an, z. B. sagt die Ausgabe nur sehr wenig über das System des Codes aus, es ist schließlich ein Dekompiler.
Ian Ringrose
3
@Ian - Sie haben Recht, das thiswird kompiliert, aber andere Dinge wie Felder mit Unterstrichpräfixen bleiben erhalten. Wenn Sie den Quellcode überprüfen, den MS jetzt herunterladen kann (und zu dem Tools wie ReSharper navigieren), werden auch in der BCL unterschiedliche Codierungsstile angezeigt.
Drew Noakes
9

Einige grundlegende Gründe für die Verwendung this(und ich stelle Klassenwerten zufällig immer den Namen der Klasse voran, zu der sie auch gehören - auch innerhalb der Klasse selbst).

1) Klarheit. Sie wissen sofort, welche Variablen Sie in der Klassendefinition deklariert und welche Sie als Lokale, Parameter und so weiter deklariert haben. In zwei Jahren werden Sie das nicht wissen und eine wundersame Wiederentdeckungsreise unternehmen, die absolut sinnlos und nicht erforderlich ist, wenn Sie die Eltern ausdrücklich im Voraus angeben. Jemand anderes, der an Ihrem Code arbeitet, hat von Anfang an keine Ahnung und profitiert daher sofort.

2) Intellisense. Wenn Sie 'this' eingeben. In der Hilfe erhalten Sie alle instanzspezifischen Mitglieder und Eigenschaften. Dies erleichtert das Auffinden von Dingen erheblich, insbesondere wenn Sie den Code oder den Code eines anderen Benutzers beibehalten, den Sie seit einigen Jahren nicht mehr angesehen haben. Es hilft Ihnen auch, Fehler zu vermeiden, die durch falsche Vorstellungen darüber verursacht werden, welche Variablen und Methoden wo und wie deklariert werden. Es kann Ihnen helfen, Fehler zu entdecken, die sonst erst auftreten würden, wenn der Compiler Ihren Code erstickt.

3) Zugegeben, Sie können den gleichen Effekt erzielen, indem Sie Präfixe und andere Techniken verwenden. Dies wirft jedoch die Frage auf, warum Sie einen Mechanismus zur Behandlung eines Problems erfinden würden, wenn es einen Mechanismus gibt, der in die Sprache integriert ist, die tatsächlich von unterstützt wird IDE? Wenn Sie auch nur teilweise tippen, wird letztendlich auch Ihre Fehlerrate reduziert, da Sie nicht gezwungen werden, Ihre Finger aus der Ausgangsposition zu nehmen, um zur Unterstrich-Taste zu gelangen.

Ich sehe viele junge Programmierer, die viel aus der Zeit machen, die sie sparen, wenn sie nicht ein oder zwei Zeichen eingeben. Die meiste Zeit wird für das Debuggen und nicht für das Codieren aufgewendet. Sorgen Sie sich nicht so sehr um Ihre Schreibgeschwindigkeit. Sorgen Sie sich mehr darum, wie schnell Sie verstehen können , was im Code vor sich geht. Wenn Sie insgesamt fünf Minuten Codierung sparen und zusätzliche zehn Minuten für das Debuggen aufwenden, haben Sie sich verlangsamt, egal wie schnell Sie aussehen .

YrthWyndandFyre
quelle
2
Ihr letzter Absatz widerspricht im Wesentlichen Ihrem dritten Punkt. Und jeder, der ein Touch-Typist ist und die Ausgangsposition verlassen muss, um zur Unterstrich-Taste zu gelangen, ist ... kein Touch-Typist.
Sliderhouserules
Ups, Tippfehler. „hat bewegen aus ...“ Es läßt mich meinen Kommentar nach 5 Minuten nicht bearbeiten.
Sliderhouserules
4

Ich folge ihm, weil ich es für sehr praktisch halte, den Zugriff auf statische und Instanzmitglieder auf den ersten Blick unterscheiden zu können.

Und natürlich muss ich es in meinen Konstruktoren verwenden, da ich den Konstruktorparametern normalerweise die gleichen Namen gebe wie dem Feld, dem ihre Werte zugewiesen werden. Also brauche ich "dies", um auf die Felder zuzugreifen.

Maximilian Mayerl
quelle
3

Darüber hinaus ist es möglich, Variablennamen in einer Funktion zu duplizieren, sodass die Verwendung von 'this' dies klarer macht.

class foo {
  private string aString;

  public void SetString(string aString){
    //this.aString refers to the class field
    //aString refers to the method parameter        
    this.aString = aString; 
  }
}
Michael Gattuso
quelle
Ich sehe diese Praxis oft in Konstruktoren, in denen die Parameter oft mit den Namen verschiedener privater Felder und / oder Eigenschaften übereinstimmen, zu denen das 'this' hinzugefügt wird. Das Präfix hilft, den Code zu verdeutlichen und in einigen Fällen Namenskollisionen zu vermeiden.
Jpierson
1

Ich folge ihm hauptsächlich aus intelligisense Gründen. Es ist so schön zu this.tippen und eine übersichtliche Liste von Eigenschaften, Methoden usw. zu erhalten.

James Lawruk
quelle
7
Gut, aber wenn Sie fertig sind, hat die Liste this.keinen Wert mehr. Bedenken Sie: Wenn Sie einen Tastendruck eingeben könnten, der dieselbe IntelliSense-Liste wie die Eingabe von " this." erzeugt, wäre die Eingabe von "'` this. "" Sehr gering.
John Saunders
Ich habe diese besondere Ausrede schon einmal gehört und sie getroffen. Für Intellisense riecht es für mich nur nach Faulheit. ist nicht erforderlich, wie der vorherige Kommentar hervorhebt. Außerdem gibt es andere Möglichkeiten, Intellisense aufzurufen.
Kirstan Ehre
Aus dem gleichen Grund habe ich '.' in Java-Code, weil, wenn ich mich richtig erinnere, Tools wie JBuilder ihn aufgreifen und Intelli-Sense bieten würden. Ich denke also, in Jave kann das Kewword 'dies' insgesamt begangen werden.
Jpierson