Ich sehe ähnliche Fragen in Bezug auf Parameternamen, die mit den Eigenschaften der Klasse übereinstimmen, kann jedoch nichts in Bezug auf die Verwendung eines Parameternamens finden, der mit dem Namen des Parametertyps identisch ist, mit Ausnahme der Groß- und Kleinschreibung in C #. Es scheint keine Verletzung zu sein, die ich finden kann, aber wird es als schlechte Praxis angesehen? Zum Beispiel habe ich die folgende Methode
public Range PadRange(Range range) {}
Diese Methode nimmt einen Bereich und gibt einen neuen Bereich zurück, auf den eine Auffüllung angewendet wurde. Angesichts des allgemeinen Kontexts kann ich mir keinen aussagekräftigeren Namen für den Parameter vorstellen. Ich erinnere mich jedoch an einen Tipp, den ich beim Lesen von Code Complete über "psychologische Distanz" erhalten habe. Es sagt
Psychologische Distanz kann als die Leichtigkeit definiert werden, mit der zwei Elemente unterschieden werden können. Seien Sie beim Debuggen auf die Probleme vorbereitet, die durch eine unzureichende psychologische Distanz zwischen ähnlichen Variablennamen und zwischen ähnlichen Routinennamen verursacht werden. Wählen Sie beim Erstellen von Code Namen mit großen Unterschieden aus, um das Problem zu vermeiden.
Meine Methodensignatur hat eine Menge "Reichweite", daher scheint es ein Problem in Bezug auf diese psychologische Distanz zu sein. Nun sehe ich viele Entwickler, die Folgendes tun
public Range PadRange(Range myRange) {}
Ich persönlich habe eine starke Abneigung gegen diese Konvention. Das Hinzufügen eines "Mein" -Präfixes zu Variablennamen bietet keinen zusätzlichen Kontext.
Ich sehe auch folgendes
public Range PadRange(Range rangeToPad) {}
Mir gefällt das besser als das "my" -Präfix, aber insgesamt interessiert es mich immer noch nicht. Es fühlt sich für mich einfach zu wortreich an und liest sich unbeholfen als Variablenname. Mir ist klar, dass der Bereich aufgrund des Methodennamens aufgefüllt wird.
Nach alledem ist es mein Magen, mit der ersten Unterschrift zu beginnen. Für mich ist es sauber. Kontext muss nicht erzwungen werden, wenn er nicht benötigt wird. Aber mache ich mir selbst oder zukünftigen Entwicklern einen schlechten Dienst mit dieser Konvention? Verstoße ich gegen eine bewährte Methode?
quelle
Range range
ist das in Ordnung.Range r
(zumindest für einen kurzen Methodenkörper) undRange toPad
.Antworten:
Denken Sie nicht darüber nach,
Range range
ist in Ordnung. Ich benutze eine solche Art der Benennung seit mehr als 15 Jahren in C # und wahrscheinlich auch länger in C ++ und habe nie echte Nachteile davon erfahren, ganz im Gegenteil.Wenn Sie verschiedene lokale Variablen desselben Typs im selben Bereich haben, ist es wahrscheinlich hilfreich, einige mentale Anstrengungen zu unternehmen, um sie richtig zu unterscheiden.
quelle
Wack(Bozo bozoToBeWacked)
als Beispiel eine Redundanz im Variablennamen betrachten, die von der Methode selbst reichlich ausgedrückt wird (und daher für die ursprüngliche Frage unerwünscht ist).Wack(Person bozo)
ist jedoch semantisch wertvoller, da damit gerechnet wird, dass nur Bozos gefälscht werden.initialRange
. Es ist immer noch sehr allgemein gehalten, hat aber nicht annähernd die gleiche Abneigung wiemyRange
.Punch(Bozo punchingBozo, Bozo bozoToBePunched)
. Eine detaillierte Benennung ist relevanter, wenn Sie zwischen mehreren Dingen unterscheiden müssen (die semantisch mit so ziemlich denselben Worten beschrieben werden). Der Vorschlag von OPRange rangeToPad
ist in seinem Beispiel für eine Ein-Parameter-Methode nicht erforderlich, kann aber für eine Methode, die mehrereRange
Objekte aufnimmt, unglaublich notwendig sein .Punch(Bozo source, Bozo target)
würde den Job machenIch mache das die ganze Zeit, es gibt mir ein großes Stück Verstand. Wenn es sich um ein Argument handelt, das an einen Konstruktor übergeben wird, der einem Member zugewiesen werden muss, erhält mein Member ebenfalls den Namen range, und die Zuweisung erfolgt
Und ich würde in der Regel eine Eigenschaft namens Range haben.
Sie sind alle gleich und unterscheiden sich nur im Kontext. Daher ist es sinnvoll, einen einzelnen Namen beizubehalten, und Sie müssen sich nur einen Namen merken. Es ist eine Sache, die Unterschiede sind rein technisch.
Sie sollten streng mit voll qualifizierten Mitgliedern mit "this" sein. aber dafür ist StyleCop da.
StyleCop Randnotiz
Kontroverse garantiert!
Für diejenigen, die sich gegen die Verwendung von "dies" aussprechen: Ich habe _, m, m_ und einfach nichts gesehen. Die Sprache selbst bietet uns eine vollkommen klare, eindeutige und allgemein erkennbare Möglichkeit, anzuzeigen, dass es sich um ein Klassenmitglied handelt. Warum um alles in der Welt wollen Sie Ihren eigenen Weg finden, der bereits perfekte Namen verstümmelt?
Der einzige Grund, warum ich daran denken kann, ist, dass es eine alte Angewohnheit aus der C-Ära ist, als es tatsächlich Sinn machte, dies zu tun, weil es keinen anderen Weg gab.
"Es sind mehr Charaktere!" Ernsthaft? "Die Kompilierungszeit wird in die Höhe schnellen!" Ernsthaft? "Ich muss meinen kleinen Finger beim Tippen heben!" Als ob die Eingabezeit für die gesamte Entwicklungszeit von Bedeutung wäre.
Ich erkenne, dass jeder andere Stil als der, an den Sie gewöhnt sind, Widerstände hervorrufen wird. Aber es ist schwer, konsequent damit umzugehen. So funktioniert es für mich: Bevor ich eine neue Codedatei pushe, starte ich StyleCop und es werden einige Mitglieder gefunden, denen "diese" Qualifikationen fehlen. Ich habe "das" gesagt. Führen Sie in der Zwischenablage die Elemente aus und fügen Sie sie ein. Überhaupt keine Anstrengung.
StyleCop kann noch viel mehr (haha). Es gibt so viele Möglichkeiten, wie ein Entwickler (nur unter Berücksichtigung der Code-Formatierung) die Wartungsarbeiten seines Nachfolgers vereiteln kann. StyleCop verhindert die meisten von ihnen. Es ist von unschätzbarem Wert.
Wenn Sie neu darin sind: In der Regel schimpfen Sie ein oder zwei Wochen lang, und dann werden Sie es lieben.
quelle
this
nur, wenn es erforderlich ist. Sonst ist es nur Lärm. Verwendung_range
für das Feld undthis
wird nur bei Erweiterungsmethoden benötigt._
gegenüber dem Rauschen von vorzuziehen istthis.
? Ich würde argumentieren, dass eine Bedeutung durch die Sprache erzwungen wird (und normalerweise Syntaxhervorhebungen aufweist), während die andere dies nicht tut.Meine Selbstanleitung zu Benennungsmethoden, Parametern und Variablen ist ziemlich einfach:
Somit wäre die optimale Methodensignatur meiner Meinung nach:
Das Kürzen des Methodennamens ist selbsterklärend.
Der Parametername
toPad
teilt dem Leser sofort mit, dass dieser Parameter wahrscheinlich direkt geändert wird, indem er aufgefüllt und dann zurückgegeben wird. Im Gegensatz dazu können keine Annahmen über eine Variable namens getroffen werdenrange
.Darüber hinaus
Range
würden (sollten) alle anderen Variablen, die eingeführt werden, nach ihrer Intention benannt, sodass Sie möglicherweise diese Namenskonventionen habenpadded
undunpadded
... sietoPad
erfüllen, aberrange
nur hervorstechen und nicht gelieren.quelle
padded
/unpadded
klingt gut für lokale unveränderliche Variablen. Wenn es jedoch einen veränderlichentoPad
Parameter gibt,toPad
passt der Name nach dem Auffüllen nicht mehr (es sei denn, das Ergebnis wird sofort zurückgegeben). Ich würde michRange range
in solchen Fällen lieber daran halten .result
. Es wird modifiziert und zurückgegeben . Letzteres geht aus dem Namen hervor und ersteres folgt, da die Rückgabe eines unveränderten Arguments keinen Sinn ergibt.Pad
Methode a zurückRange
. Dies bedeutet für mich, dass der von mir übergebene beibehalten und nicht an Ort und Stelle geändert wird und ein neuer, gepolsterter zurückgegebenRange
wird. .Pad(toPad)
fühlt sich irgendwie falsch IMHO. Sie verteidigen Ihren Standpunkt jedoch sehr gut. Du bekommst eine +0 von mir! :)Für die Benennung von Codeelementen (Typen, Variablen, Funktionen usw.) ist die Schlüsselfrage, die Sie sich stellen müssen
Wenn ich einen Tippfehler mache, findet der Compiler ihn dann für mich?
Die schlimmste Art von typobasiertem Fehler ist ein Fehler, bei dem der Code kompiliert und ausgeführt wird, der sich jedoch aus subtilen Gründen anders verhält als erwartet. Und da es sich um einen Tippfehler handelt, ist es normalerweise sehr schwer zu erkennen, wann Sie den Code überprüfen. Wenn ein Tippfehler die Codekompilierung stoppt, markiert der Compiler die Zeile, die das Problem verursacht, und Sie können es leicht finden und beheben.
In Ihrer Situation, in der sich Typ und Variable nur in der Groß- und Kleinschreibung unterscheiden, ist dies immer der Fall. (Oder fast immer - mit ausreichendem Aufwand, ich bin mir sicher, dass Sie es schaffen könnten, aber Sie müssten es wirklich versuchen.) Also denke ich, dass es Ihnen gut geht.
Wenn es zwei Variablen, Methoden, Funktionen oder Eigenschaften im aktuellen Gültigkeitsbereich gibt, die als
range
und bezeichnet werden, wären Sie besorgtRange
. In diesem Fall wird der Compiler wahrscheinlich wird lassen Sie es durch, und Sie werden unerwartetes Verhalten zur Laufzeit erhalten. Beachten Sie, dass das ist , zwei von jedem dieser Arten von Code - Elemente, nicht nur „zwei Variablen“ oder „zwei Funktionen“ - alle diese können implizit miteinander gegossen wird, mit resultierendem Blutbad , wenn es läuft. Möglicherweise erhalten Sie Warnungen, aber Sie können nicht mehr als das garantieren. Sie haben ähnliche Probleme, wenn Sie zwei Typen als aufgerufenrange
und deklariert hattenRange
.Beachten Sie auch, dass dies auch für den ungarischen Notationsstil gilt , bei dem den Namen ein oder mehrere Zeichen vorangestellt werden, um etwas mehr darüber zu sagen, was auch immer es ist. Wenn eine Variable aufgerufen wird
Range
und ein Zeiger darauf aufgerufen wirdPRange
, kann dies beispielsweise leicht versehentlich übersehen werdenP
. C # sollte dies auffangen, aber C und C ++ geben Ihnen höchstens eine Warnung. Angenommen, Sie haben eine Double-Version mit dem Namen "DRange
Float ", und Sie haben eine Downsampling-Version mit dem Namen "Float"FRange
. Verwenden Sie den Schwimmer ein durch einen Unfall (die einfach ist , da die Tasten auf einer Tastatur benachbart sind) und Ihr Code Art von Arbeit, aber es wird in seltsame und unvorhersehbare Weise umfallen , wenn der Prozess der Auflösung abläuft und Unterschreitungen.Wir sind nicht mehr in den Tagen, in denen wir Namensbeschränkungen von 8 Zeichen oder 16 Zeichen oder eine beliebige Beschränkung hatten. Ich habe manchmal gehört, wie Anfänger sich über längere Variablennamen beschwerten, was dazu führte, dass die Codierung länger dauerte. Es sind jedoch immer nur Anfänger, die sich darüber beschweren. Seriöse Programmierer wissen, dass es wirklich Zeit braucht, obskure Fehler zu finden - und eine falsche Namenswahl ist ein klassischer Weg, um sich in diese bestimmte Lücke fallen zu lassen.
quelle
Eine Anekdote, die ich hinzufügen möchte:
Range range
Dies ist zwar syntaktisch zulässig, könnte jedoch das Debuggen oder Umgestalten schwieriger machen. Suchen Sie nach dieser einen Variablen mit dem Namen "range" in einer Datei mit vielen Variablen vom Typ Range? Aufgrund dieser Benennungsoption können Sie später möglicherweise mehr Arbeit erledigen.Dies ist jedoch weitgehend kontextabhängig. Wenn es sich um eine 30-zeilige Datei handelt, kommen meine Aussagen nicht wirklich ins Spiel.
quelle
grep
ist ein großartiges Tool, aber kein Refactoring-Tool. Und Refactoring-Tools gibt es auf jeder Entwicklungsplattform, die ich verwendet habe. (OS X, Ubuntu, Windows).Ich denke, Sie können
Range range
nowdays aus einem Grund verwenden: Syntaxhervorhebung. Moderne IDEs heben in der Regel die Typnamen und die Parameternamen in verschiedenen Farben hervor . Auch ein Typ und eine Variable haben einen beträchtlichen "logischen Abstand", der nicht leicht zu verwechseln ist.Wäre dies nicht der Fall, würde ich einen anderen Namen in Betracht ziehen oder versuchen, ein Plugin / eine Erweiterung zu aktivieren, das / die diese Syntaxhervorhebung ausführen kann.
quelle
Wenn eine Funktion generisch ist, liegt es nahe, dass die Parameter generisch sind und daher generische Namen haben sollten.
Nicht das, was Sie sagen, aber ich habe Funktionen gesehen, die eine generische Funktion ausführen, deren Parameternamen irreführend spezifisch sind. Mögen
Der Funktionsname klingt sehr allgemein, so dass er in vielen Situationen auf viele Zeichenfolgen angewendet werden kann. Aber der Parametername ist seltsamerweise spezifisch, was mich fragt, ob der Funktionsname irreführend ist oder ... was?
Anstatt Range range zu sagen, können Sie Range rangeToPad sagen. Aber welche Informationen fügt dies hinzu? Natürlich ist es der zu polsternde Bereich. Was wäre es noch?
Das Hinzufügen eines beliebigen Präfixes, "my" oder "m_" oder was auch immer, übermittelt dem Leser keine zusätzlichen Informationen. Wenn ich Sprachen verwendet habe, in denen der Compiler nicht zulässt, dass ein Variablenname mit einem Typennamen übereinstimmt - mit oder ohne Berücksichtigung der Groß- / Kleinschreibung -, habe ich manchmal ein Präfix oder ein Suffix angegeben, um es zum Kompilieren zu bringen . Aber das ist nur, um den Compiler zufrieden zu stellen. Man könnte argumentieren, dass selbst wenn der Compiler unterscheiden kann, dies einem menschlichen Leser das Unterscheiden erleichtert. Aber wow, in Java habe ich Aussagen wie "Kunde Kunde = neuer Kunde ();" geschrieben. eine Milliarde Mal und ich fand es nie verwirrend. (Ich fand es immer ein bisschen überflüssig, und ich mag es, dass Sie in VB einfach "Kunden als neuen Kunden dimmen" sagen können und den Klassennamen nicht zweimal eingeben müssen.)
Ich lehne generische Namen entschieden ab, wenn zwei oder mehr Instanzen desselben Typs in derselben Funktion vorhanden sind. INSBESONDERE Parameter. Mögen:
Was ist der Unterschied zwischen range1 und range2? Woher soll ich das wissen? Wenn es etwas ist, bei dem es sich wirklich um zwei generische und austauschbare Werte handelt, okay, wie
Ich würde erwarten, dass dies true zurückgibt, wenn sich die Bereiche überlappen, und false, wenn dies nicht der Fall ist. Daher sind sie generisch und austauschbar.
Aber wenn sie anders sind, gib mir einen Hinweis, wie sie anders sind! Ich habe gerade an einem Programm gearbeitet, das eine "Place" -Klasse zum Speichern von Daten über geografische Orte und mit Variablen dieses Typs namens "p", "place", "place2", "myPlace" usw. hatte. Wow, diese Namen helfen mir wirklich zu bestimmen, welche welche ist.
quelle