Frage

Ich war neugierig, wie andere Leute das nutzen Das Stichwort.Ich verwende es normalerweise in Konstruktoren, kann es aber auch in anderen Methoden in der gesamten Klasse verwenden.Einige Beispiele:

In einem Konstruktor:

public Light(Vector v)
{
    this.dir = new Vector(v);
}

Anderswo

public void SomeMethod()
{
    Vector vec = new Vector();
    double d = (vec * vec) - (this.radius * this.radius);
}
War es hilfreich?

Lösung

Es gibt mehrere Verwendungen von Das Schlüsselwort in C#.

  1. Um Mitglieder zu qualifizieren, die unter einem ähnlichen Namen verborgen sind
  2. Damit ein Objekt sich selbst als Parameter an andere Methoden übergibt
  3. Damit ein Objekt sich selbst von einer Methode zurückgibt
  4. So deklarieren Sie Indexer
  5. Zum Deklarieren von Erweiterungsmethoden
  6. Um Parameter zwischen Konstruktoren zu übergeben
  7. Um den Werttyp (Struktur) intern neu zuzuweisen.
  8. Zum Aufrufen einer Erweiterungsmethode für die aktuelle Instanz
  9. Sich in einen anderen Typ umwandeln
  10. Zum Verketten von Konstruktoren, die in derselben Klasse definiert sind

Sie können die erste Verwendung vermeiden, indem Sie keine Mitglieds- und lokalen Variablen mit demselben Namen im Gültigkeitsbereich haben, indem Sie beispielsweise allgemeine Namenskonventionen befolgen und Eigenschaften (Pascal-Fall) anstelle von Feldern (Kamel-Fall) verwenden, um Kollisionen mit lokalen Variablen (auch Kamel-Fall) zu vermeiden Fall).In C# 3.0 können Felder mithilfe von einfach in Eigenschaften umgewandelt werden automatisch implementierte Eigenschaften.

Andere Tipps

Ich möchte nicht, dass das bissig klingt, aber es spielt keine Rolle.

Ernsthaft.

Schauen Sie sich die Dinge an, die wichtig sind:Ihr Projekt, Ihr Code, Ihr Job, Ihr Privatleben.Bei keinem von ihnen hängt der Erfolg davon ab, ob Sie das Schlüsselwort „this“ verwenden, um den Zugriff auf Felder zu qualifizieren.Das Schlüsselwort this hilft Ihnen nicht dabei, pünktlich zu versenden.Es wird keine Fehler reduzieren und keine nennenswerten Auswirkungen auf die Qualität oder Wartbarkeit des Codes haben.Dadurch erhalten Sie weder eine Gehaltserhöhung noch müssen Sie weniger Zeit im Büro verbringen.

Es ist wirklich nur eine Stilfrage.Wenn Ihnen „dies“ gefällt, dann verwenden Sie es.Wenn nicht, dann nicht.Wenn Sie es benötigen, um die korrekte Semantik zu erhalten, verwenden Sie es.Die Wahrheit ist, dass jeder Programmierer seinen eigenen einzigartigen Programmierstil hat.Dieser Stil spiegelt die Vorstellungen des jeweiligen Programmierers darüber wider, wie der „ästhetisch ansprechendste Code“ aussehen sollte.Per Definition wird jeder andere Programmierer, der Ihren Code liest, einen anderen Programmierstil haben.Das bedeutet, dass es immer etwas geben wird, was der andere nicht mag oder was er anders gemacht hätte.Irgendwann wird jemand Ihren Code lesen und sich über etwas beschweren.

Ich würde mir darüber keine Sorgen machen.Ich würde einfach sicherstellen, dass der Code so ästhetisch wie möglich ist und Ihrem Geschmack entspricht.Wenn Sie 10 Programmierer fragen, wie man Code formatiert, erhalten Sie etwa 15 unterschiedliche Meinungen.Man sollte sich besser darauf konzentrieren, wie der Code faktorisiert wird.Sind die Dinge richtig abstrahiert?Habe ich aussagekräftige Namen für Dinge gewählt?Gibt es viele Codeduplizierungen?Gibt es Möglichkeiten, Dinge zu vereinfachen?Wenn Sie diese Dinge richtig machen, wird es meiner Meinung nach den größten positiven Einfluss auf Ihr Projekt, Ihren Code, Ihren Job und Ihr Leben haben.Zufälligerweise wird es wahrscheinlich auch dazu führen, dass der andere am wenigsten meckert.Wenn Ihr Code funktioniert, leicht zu lesen und gut faktorisiert ist, wird der andere nicht genau prüfen, wie Sie Felder initialisieren.Er wird einfach Ihren Code verwenden, über seine Großartigkeit staunen und dann zu etwas anderem übergehen.

Ich verwende es nur, wenn es absolut notwendig ist, z. B. wenn eine andere Variable eine andere überschattet.So wie hier:

class Vector3
{
    float x;
    float y;
    float z;

    public Vector3(float x, float y, float z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

}

Oder wie Ryan Fox betont, wenn Sie dies als Parameter übergeben müssen.(Lokale Variablen haben Vorrang vor Mitgliedsvariablen)

Persönlich versuche ich, immer zu verwenden Das wenn auf Mitgliedsvariablen Bezug genommen wird.Es hilft, den Code zu verdeutlichen und lesbarer zu machen.Selbst wenn es keine Unklarheiten gibt, weiß das jemand, der meinen Code zum ersten Mal durchliest, nicht, aber wenn er es sieht Das Bei konsequenter Verwendung wissen sie, ob sie eine Mitgliedsvariable betrachten oder nicht.

Ich verwende es jedes Mal, wenn ich auf eine Instanzvariable verweise, auch wenn es nicht nötig ist.Ich denke, es macht den Code klarer.

Ich kann nicht allen Leuten glauben, die sagen, es sei immer eine „Best Practice“ und so weiter.

Verwenden Sie „this“, wenn Unklarheiten bestehen, wie z Coreys Beispiel oder wenn Sie das Objekt als Parameter übergeben müssen, wie in Ryans Beispiel.Es gibt keinen Grund, es anders zu verwenden, da die Möglichkeit, eine Variable basierend auf der Bereichskette aufzulösen, klar genug sein sollte, dass die Qualifizierung von Variablen damit unnötig sein sollte.

BEARBEITEN:Die C#-Dokumentation zu „this“ weist neben den beiden erwähnten noch auf eine weitere Verwendung des Schlüsselworts „this“ hin: zum Deklarieren von Indexern

BEARBEITEN:@Juan:Huh, ich sehe keine Inkonsistenz in meinen Aussagen – es gibt drei Fälle, in denen ich das Schlüsselwort „this“ verwenden würde (wie in der C#-Dokumentation dokumentiert), und das sind Zeiten, in denen Sie tatsächlich brauchen Es.„Dies“ vor Variablen in einem Konstruktor einzufügen, wenn kein Shadowing stattfindet, ist einfach eine Verschwendung von Tastenanschlägen und eine Verschwendung meiner Zeit beim Lesen, es bringt keinen Nutzen.

Ich benutze es wann immer StyleCop sagt es mir. StyleCop muss gehorcht werden.Oh ja.

Immer wenn Sie einen Verweis auf das aktuelle Objekt benötigen.

Ein besonders praktisches Szenario ist, wenn Ihr Objekt eine Funktion aufruft und sich selbst an diese übergeben möchte.

Beispiel:

void onChange()
{
    screen.draw(this);
}

Ich neige dazu, es auch überall zu verwenden, nur um sicherzustellen, dass klar ist, dass es sich um Instanzmitglieder handelt, mit denen wir es zu tun haben.

Ich verwende es überall dort, wo Unklarheiten bestehen könnten (natürlich).Nicht nur die Mehrdeutigkeit des Compilers (in diesem Fall wäre dies erforderlich), sondern auch die Mehrdeutigkeit für jemanden, der sich den Code ansieht.

Eine weitere eher seltene Verwendung des Schlüsselworts this besteht darin, dass Sie eine explizite Schnittstellenimplementierung innerhalb der implementierenden Klasse aufrufen müssen.Hier ist ein erfundenes Beispiel:

class Example : ICloneable
{
    private void CallClone()
    {
        object clone = ((ICloneable)this).Clone();
    }

    object ICloneable.Clone()
    {
        throw new NotImplementedException();
    }
}

Hier ist, wann ich es verwende:

  • Zugriff auf private Methoden innerhalb der Klasse (zur Unterscheidung)
  • Übergabe des aktuellen Objekts an eine andere Methode (oder als Senderobjekt im Falle eines Ereignisses)
  • Beim Erstellen von Erweiterungsmethoden :D

Ich verwende dies nicht für private Felder, da ich den Variablennamen privater Felder einen Unterstrich (_) voranstelle.

[C++]

Ich stimme mit der „Benutze es, wenn du musst“-Brigade überein.Code unnötigerweise dekorieren mit Das ist keine gute Idee, da der Compiler Sie nicht warnt, wenn Sie dies vergessen.Dies führt zu potenzieller Verwirrung für Personen, die dies erwarten Das immer da sein, d.h.Sie werden es müssen denken darüber.

Wann würden Sie es also verwenden?Ich habe mich gerade in zufälligem Code umgeschaut und diese Beispiele gefunden (ob das so ist, kann ich nicht beurteilen). Gut Dinge, die zu tun sind oder nicht):

  • „Sich selbst“ an eine Funktion übergeben.
  • „Sich selbst“ einem Zeiger oder ähnlichem zuweisen.
  • Casting, d.h.Up/Down-Casting (sicher oder nicht), Konstanz wegwerfen usw.
  • Der Compiler hat die Begriffsklärung erzwungen.

Ich verwende es, wenn ich es in einer Funktion erstellen möchte, die einen Verweis auf ein Objekt desselben Typs akzeptiert absolut klar welches Objekt ich meine, wo.

Zum Beispiel

class AABB
{
  // ... members
  bool intersects( AABB other )
  {
    return other.left() < this->right() &&
           this->left() < other.right() &&

           // +y increases going down
           other.top() < this->bottom() &&
           this->top() < other.bottom() ;
  }
} ;

(vs)

class AABB
{
  bool intersects( AABB other )
  {
    return other.left() < right() &&
           left() < other.right() &&

           // +y increases going down
           other.top() < bottom() &&
           top() < other.bottom() ;
  }
} ;

Auf einen Blick, was AABB macht right() beziehen auf?Der this fügt ein wenig Klarheit hinzu.

In Jakub Šturcs Antwort könnte seine Nr. 5 über die Weitergabe von Daten zwischen Konstrukteuren wahrscheinlich eine kleine Erklärung gebrauchen.Dies geschieht beim Überladen von Konstruktoren und ist der einzige Fall, in dem von verwendet wird this ist obligatorisch.Im folgenden Beispiel können wir den parametrisierten Konstruktor vom parameterlosen Konstruktor mit einem Standardparameter aufrufen.

class MyClass {
    private int _x
    public MyClass() : this(5) {}
    public MyClass(int v) { _x = v;}
}

Ich habe festgestellt, dass dies gelegentlich eine besonders nützliche Funktion ist.

Sie sollten es immer verwenden, ich verwende es, um private Felder und Parameter zu unterscheiden (da unsere Namenskonventionen besagen, dass wir keine Präfixe für Mitglieds- und Parameternamen verwenden (und sie auf Informationen basieren, die im Internet gefunden wurden, daher denke ich, dass a beste Übung))

Ich habe mir angewöhnt, es in Visual C++ großzügig zu verwenden, da dies IntelliSense-Befehle auslösen würde. Ich drücke die Taste „>“ und bin faul.(und anfällig für Tippfehler)

Aber ich habe es weiterhin verwendet, da ich es praktisch finde, zu sehen, dass ich eine Mitgliedsfunktion und nicht eine globale Funktion aufrufe.

Ich neige dazu, Felder mit _ zu unterstreichen, daher muss ich das eigentlich nie verwenden.Außerdem neigt R# dazu, sie ohnehin wegzurefaktorieren ...

Ich benutze so ziemlich nur Das wenn auf eine Typeigenschaft innerhalb desselben Typs verwiesen wird.Wie ein anderer Benutzer erwähnte, unterstreiche ich auch lokale Felder, damit sie ohne Notwendigkeit sichtbar sind Das.

Ich verwende es nur bei Bedarf, mit Ausnahme von symmetrischen Operationen, die aufgrund des Polymorphismus einzelner Argumente in Methoden einer Seite eingefügt werden müssen:

boolean sameValue (SomeNum other) {
   return this.importantValue == other.importantValue;
} 

[C++]

Das wird im Zuweisungsoperator verwendet, wo Sie die meiste Zeit seltsame (unbeabsichtigte, gefährliche oder einfach nur Zeitverschwendung für das Programm) Dinge überprüfen und verhindern müssen, wie zum Beispiel:

A a;
a = a;

Ihr Zuweisungsoperator wird geschrieben:

A& A::operator=(const A& a) {
    if (this == &a) return *this;

    // we know both sides of the = operator are different, do something...

    return *this;
}

this auf einem C++-Compiler

Der C++-Compiler sucht stillschweigend nach einem Symbol, wenn er es nicht sofort findet.Manchmal, meistens, ist es gut:

  • Verwenden Sie die Methode der Mutterklasse, wenn Sie sie in der untergeordneten Klasse nicht überladen haben.
  • Heraufstufen eines Werts eines Typs in einen anderen Typ

Aber manchmal, Sie möchten einfach nicht, dass der Compiler es errät.Sie möchten, dass der Compiler das richtige Symbol erkennt und nicht ein anderes.

Für mich, Dies sind die Zeiten, in denen ich innerhalb einer Methode auf eine Mitgliedsmethode oder Mitgliedsvariable zugreifen möchte.Ich möchte einfach nicht, dass ein beliebiges Symbol ausgewählt wird, nur weil ich geschrieben habe printf anstatt print. this->printf hätte nicht kompiliert.

Der Punkt ist, dass bei C-Legacy-Bibliotheken (§), Legacy-Code, der vor Jahren geschrieben wurde (§§) oder was auch immer in einer Sprache passieren kann, in der Kopieren/Einfügen eine veraltete, aber immer noch aktive Funktion ist, manchmal der Compiler angewiesen wird, nicht abzuspielen Verstand ist eine tolle Idee.

Dies sind die Gründe, die ich verwende this.

(§) Es ist mir immer noch ein Rätsel, aber ich frage mich jetzt, ob die Tatsache, dass Sie den Header <windows.h> in Ihre Quelle einfügen, der Grund dafür ist, dass alle Symbole der alten C-Bibliotheken Ihren globalen Namensraum verschmutzen

(§§) Zu erkennen, dass „Sie einen Header einfügen müssen, aber dass das Einfügen dieses Headers Ihren Code kaputt macht, weil er ein dummes Makro mit einem generischen Namen verwendet“, ist eine davon Russisches Roulette Momente im Leben eines Programmierers

'Das.' Hilft bei der Suche nach Mitgliedern in dieser Klasse mit vielen Mitgliedern (normalerweise aufgrund einer tiefen Erbschaftskette).

Das Drücken von STRG+Leertaste hilft dabei nicht, da es auch Typen einschließt;wo-als 'das'. beinhaltet nur Mitglieder.

Normalerweise lösche ich es, sobald ich das habe, wonach ich gesucht habe:Aber das ist nur der Durchbruch meines Stils.

Was den Stil angeht: Wenn Sie ein Einzelgänger sind, entscheiden Sie;Wenn Sie für ein Unternehmen arbeiten, halten Sie sich an die Unternehmensrichtlinien (schauen Sie sich die Dinge in der Quellcodeverwaltung an und sehen Sie, was andere Leute tun).Im Hinblick auf die Verwendung zur Qualifizierung von Mitgliedern ist weder richtig noch falsch.Das einzig Falsche ist Inkonsistenz – das ist die goldene Regel des Stils.Hören Sie auf, andere pingelig zu machen.Verbringen Sie stattdessen Ihre Zeit damit, über echte Codierungsprobleme nachzudenken – und natürlich über das Codieren.

Es hängt vom Codierungsstandard ab, unter dem ich arbeite.Wenn wir _ verwenden, um eine Instanzvariable zu bezeichnen, wird „this“ überflüssig.Wenn wir nicht _ verwenden, neige ich dazu, dies zur Bezeichnung einer Instanzvariablen zu verwenden.

Ich benutze es zum Aufrufen Intellisense so wie JohnMcG, aber ich gehe zurück und lösche „this->“, wenn ich fertig bin.Ich folge der Microsoft-Konvention, Mitgliedsvariablen das Präfix „m_“ voranzustellen, daher wäre es einfach überflüssig, es als Dokumentation zu belassen.

1 – Gängige Java-Setter-Redewendung:

 public void setFoo(int foo) {
     this.foo = foo;
 }

2 – Beim Aufruf einer Funktion mit diesem Objekt als Parameter

notifier.addListener(this);

Ich benutze es jedes Mal, wenn ich kann.Ich glaube, dass dadurch der Code besser lesbar wird, und besser lesbarer Code bedeutet weniger Fehler und mehr Wartbarkeit.

Wenn viele Entwickler an derselben Codebasis arbeiten, benötigen Sie einige Coderichtlinien/-regeln.Wo ich arbeite, haben wir uns entschieden, „this“ für Felder, Eigenschaften und Ereignisse zu verwenden.

Für mich macht es durchaus Sinn, es so zu machen, denn es macht den Code leichter lesbar, wenn man zwischen Klassenvariablen und Methodenvariablen unterscheidet.

Es gibt eine Verwendung, die in C++ noch nicht erwähnt wurde und die nicht darin besteht, auf das eigene Objekt zu verweisen oder einen Member von einer empfangenen Variablen zu unterscheiden.

Sie können verwenden this um einen nicht abhängigen Namen in einen argumentabhängigen Namen innerhalb von Vorlagenklassen umzuwandeln, die von anderen Vorlagen erben.

template <typename T>
struct base {
   void f() {}
};

template <typename T>
struct derived : public base<T>
{
   void test() {
      //f(); // [1] error
      base<T>::f(); // quite verbose if there is more than one argument, but valid
      this->f(); // f is now an argument dependent symbol
   }
}

Vorlagen werden mit einem Zwei-Pass-Mechanismus kompiliert.Beim ersten Durchgang werden nur nicht-argumentabhängige Namen aufgelöst und überprüft, während abhängige Namen nur auf Kohärenz überprüft werden, ohne die Vorlagenargumente tatsächlich zu ersetzen.

In diesem Schritt hat der Compiler, ohne den Typ tatsächlich zu ersetzen, fast keine Informationen darüber, was base<T> könnte sein (beachten Sie, dass die Spezialisierung der Basisvorlage sie in völlig andere Typen, sogar undefinierte Typen, umwandeln kann), also geht sie einfach davon aus, dass es sich um einen Typ handelt.Zu diesem Zeitpunkt der unabhängige Anruf f das für den Programmierer ganz natürlich erscheint, ist ein Symbol, das der Compiler als Mitglied finden muss derived oder beim Einschließen von Namespaces – was im Beispiel nicht der Fall ist – und es wird sich beschweren.

Die Lösung besteht darin, den nicht abhängigen Namen umzuwandeln f in einen abhängigen Namen.Dies kann auf verschiedene Arten erfolgen, indem explizit der Typ angegeben wird, in dem es implementiert ist (base<T>::f --Hinzufügen der base<T> macht das Symbol abhängig von T und der Compiler geht einfach davon aus, dass es existiert, und verschiebt die eigentliche Prüfung auf den zweiten Durchgang nach der Argumentersetzung.

Der zweite Weg, der viel einfacher ist, wenn Sie von Vorlagen erben, die mehr als ein Argument oder lange Namen haben, besteht darin, einfach ein hinzuzufügen this-> vor dem Symbol.Da die von Ihnen implementierte Vorlagenklasse von einem Argument abhängt (von dem sie erbt). base<T>) this-> ist argumentabhängig und wir erhalten das gleiche Ergebnis: this->f wird in der zweiten Runde nach dem Ersetzen der Vorlagenparameter überprüft.

Sie sollten „this“ nicht verwenden, es sei denn, dies ist unbedingt erforderlich.

Unnötige Ausführlichkeit ist mit einer Strafe verbunden.Sie sollten nach Code streben, der genau so lang ist, wie er sein muss, und nicht länger.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top