Laden...

Wann wird "this." benötigt?

Erstellt von nodesperado vor 14 Jahren Letzter Beitrag vor 14 Jahren 2.789 Views
N
nodesperado Themenstarter:in
2 Beiträge seit 2010
vor 14 Jahren
Wann wird "this." benötigt?

Hallo,

ich habe vor wenigen Tagen damit begonnen C# zu erlernen und bin auf ein Beispiel aus meinem Lehrbuch gestoßen, das ich nicht ganz versteh und möchte dazu folgendes wissen:
In der Methode DatenAusgabe wird ohne this auf die Variablen des Objektes zugegriffen und in der Methode GehaltErhoehen wird this verwendet. Wonach richtet es sich, ob man this verwendet?
Die generelle Funktion von this als Verweis auf das aktuelle Objekt ist mir bewusst, aber der unterschiedliche Einsatz ist mir rätselhaft.


class Mitarbeiter
{
    string name;
    string vorname;

    int gehalt; // Monatsgehalt

    public Mitarbeiter(string name, string vorname, int gehalt)
    {
        this.name = name;
        this.vorname = vorname;
        this.gehalt = gehalt;
    }

    public void DatenAusgabe()
    {
        Console.WriteLine();
        Console.WriteLine("Name    : " + name);
        Console.WriteLine("Vorname : " + vorname);
        Console.WriteLine("Gehalt  : " + gehalt + " Euro");
    }

    public void GehaltErhoehen(int erhoehung)
    {
        this.gehalt += erhoehung;
    }
}

Ich konnte leider nichts passendes im Forum finden und hoffe, dass die Frage schnell beantwortet ist.

Vielen Dank im Voraus!

MfG noDesperado

390 Beiträge seit 2008
vor 14 Jahren

Hallo nodesperado

Eigentlich macht es gar keinen Unterschied. Brauchen tut man this nur, wenn eine lokale Variable mit demselben Namen wie eine Membervariable definiert wurde und man zwischen den beiden unterscheiden möchte. Oder bei deinem Beispiel ist im Konstruktor eine lokale Variable name definiert, wenn du nun auf diese Variable blendet sozusagen die Membervariable name aus. Um trotzdem auf die Membervariable zugreifen zu können, benutzt man eben this. Ob man this grundsätzlich immer benutzen soll oder nur wenn es nötig ist, muss jeder für sich selbst wissen. Tatsache ist, dass Dir Intellisense direkt alle Member und Methoden der aktuellen Klasse anzeigt, wenn du this. eingibst.

Gruss

using Skill

5.942 Beiträge seit 2005
vor 14 Jahren

Salute nodesperado

Wie edsplash schon geschrieben hat, brauchst du "this" grundsätzlich nur, wenn du die Referenz auf das aktuelle Objekt brauchst.
Üblicherweise wird "this" auch verwendet, wenn die übergebenen Argumente gleich benannt sind, wie Instanzvariablen, bspw.:


public class Foo
{
    private string bar;

    public Foo(string bar)
    {
        this.bar = bar;
    }
}

Ansonsten kann "this" nach Belieben verwendet werden, enweder um Intellisense auf der aktuellen Instanz zu bekommen, oder aber um zu unterstreichen, dass auf das aktuelle Objekt zugegriffen wird.

Wenn ich in ASP.NET bspw. auf "IsPostBack" zugreife, ist auf den ersten Blick nicht klar, worum es sich handelt. Bei "this.IsPostBack" weiss ich sofort das ich auf die Instanzvariable "IsPostBack" der aktuellen Instanz - in diesem Fall der Page - zugreife.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo edsplash,

Oder bei deinem Beispiel ist im Konstruktor eine lokale Variable name definiert

nö, es gibt einen Parameter mit dem Namen name. Parameter und lokale Variablen sollte man schon sauber von einander trennen. 😃

Hallo Peter Bucher,

Wie edsplash schon geschrieben hat, brauchst du "this" grundsätzlich nur, wenn du die Referenz auf das aktuelle Objekt brauchst.

die Formulierung finde ich etwas unglücklich, denn this**.** muss man gerade nicht an allen Stellen benutzen, wo man die Referenz auf das aktuelle Objekt braucht, sondern kann es als Schreiberleichterung weglassen. Es wird dann an vielen Stellen vom Compiler automatisch ergänzt.

Hallo nodesperado,

das Weglassen von this**.** ist eine - in meinen Augen - sehr sinnvolle Schreib- und Leseerleicherung, von der man wo immer möglich Gebrauch machen sollte. An den Stellen, wo man this**.** weglassen darf, wird genau der gleiche Code erzeugt, als wenn man this**.** geschrieben hätte. Nur in den Fällen, wo Mehrdeutigkeiten vorliegen (z.B. in dem Konstruktor im Beispiel) oder wo this unbedingt benötigt wird (z.B. wenn man die eigene Instanz per Parameter an eine andere Methode übergeben will), muss man this explizit schreiben.

Lustigerweise stellen sich die meisten Programmierer die Frage, ob man this**.** weglassen sollte oder nicht nur bei Membervariablen und Properties, nicht aber bei (Instanz-)Methoden, obwohl sie sich da ganz genauso stellt. Ohne die Schreiberleichterung des Compilers müsste man auch vor alle (Instanz-)Methoden this**.** schreiben. Und selbst die Programmierer, die finden, dass man unbedingt this**.** schreiben muss, schreiben this**.** nur vor Membervariablen und Properties, nicht aber vor (Instanz-)Methoden.

Ob man this grundsätzlich immer benutzen soll oder nur wenn es nötig ist, muss jeder für sich selbst wissen ...

... und wurde auch schon in mehreren Threads ausführlich diskutiert, u.a. in this.XXXXX.

herbivore

H
116 Beiträge seit 2008
vor 14 Jahren

Moin!

Auch bei mehreren Konstruktoren kann this. benötigt werden.

class Foo : Bar
{
    private string aString;

    public Foo()
        : base()
    {
        aString = string.Empty;
    }

    public Foo(string myNewString)
        : this()
    {
        aString = myNewString;
    }
}

Hinrich

925 Beiträge seit 2004
vor 14 Jahren

Parameter und lokale Variablen sollte man schon sauber von einander trennen. 😃

Sollte man das? Im Falle von Call by Value verhalten sich diese doch absolut identisch.

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo 7.e.Q,

ja, sollte man unbedingt. Selbst wenn die Verwendung gleich ist, ist die Deklaration, die Art der Initialisierung und vor allem das Konzept sehr unterschiedlich. Man kommt ja auch nicht auf die Idee ein (öffentliches) Field Property nennen oder eine Property Field ein nur weil man es über weite Strecken keinen Unterschied spürt. Zumindest sollte man das nicht tun. Aber das ist wirklich nicht das Thema hier.

herbivore

771 Beiträge seit 2009
vor 14 Jahren

Und selbst die Programmierer, die finden, dass man unbedingt this. schreiben muss, schreiben this. nur vor Membervariablen und Properties, nicht aber vor (Instanz-)Methoden.

Diese Programmierer tun dies, um explizit zwischen Member- und lokalen Variablen (bzw. Parametern) zu unterscheiden (falls dafür dieselbe Namensgebung benutzt wird).
Für Methoden ist es ja dann eindeutig, da es keine lokalen Methoden gibt.
Beispiel (für diesen CodeStyle):


// Variablen immer kleingeschrieben
private int x;
private int y;

private void Set(int x, int y)
{
   this.x = x;
   this.y = y;
}

public void Reset()
{
   int x = 42;
   int y = 10;

   Set(x, y); // <- Methodennamen fangen mit großem Buchstaben an
}

Daher kann hier "this." beim Aufruf der Methode entfallen - einfach weil es hier eindeutig ist, welches 'Set' gemeint ist.
Ich kenne aber auch keinen CodeStyle, der das explizit fordert - der Mensch neigt eh zu Verkürzungen, da man sonst ja nur noch "this." lesen würde - also der gegenteilige Effekt eintreten würde.

390 Beiträge seit 2008
vor 14 Jahren

Hallo herbivore

Du hast natürlich recht, allerdings denke ich spielt es für die Beschreibung des Problems keine Rolle ob lokale Variable oder Parameter. 😉

Gruss

using Skill

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo Cat,

Für Methoden ist es ja dann eindeutig, da es keine lokalen Methoden gibt.

nein, denn es gibt statische Methoden. Deshalb ist es ohne this bzw. ohne den Klassennamen vor Methoden für den Leser, der nur die Aufrufstelle sieht, auch nicht eindeutig, welche Art von Methode gemeint ist.

Oder andersherum gesehen: Auch bei Variablen ist auch ohne this immer eindeutig definiert, was gemeint ist. Wäre es nicht eindeutig definiert, könnte der Compiler ja keinen Code erzeugen.

Davon abgesehen halte ich es für ungünstig, sich darauf zu verlassen, dass alle Variablen, die nicht mit this gekennzeichnet sind, keine Membervariablen sind, denn this ist schnell mal vergessen und der Compiler meckert dann ja gerade nicht.

Was mich wieder dazu führt, dass man this nur an den Stellen verwenden sollte, wo es sich nicht vermeiden lässt.

herbivore

5.942 Beiträge seit 2005
vor 14 Jahren

Hallo herbivore

die Formulierung finde ich etwas unglücklich, denn this**.** muss man gerade nicht an allen Stellen benutzen, wo man die Referenz auf das aktuelle Objekt braucht, sondern kann es als Schreiberleichterung weglassen. Es wird dann an vielen Stellen vom Compiler automatisch ergänzt.

Öhm, ich meinte damit auch nur die Verwendung von "this" alleine, also eine Referenz auf das Objekt, nicht auf einen Member des Objekts.

Lustigerweise stellen sich die meisten Programmierer die Frage, ob man this**.** weglassen sollte oder nicht nur bei Membervariablen und Properties, nicht aber bei (Instanz-)Methoden, obwohl sie sich da ganz genauso stellt.

Dann gehöre ich nicht zu den meisten. So kann man statische Methoden von Instanzmethoden unterscheiden, ohne lang rumzusuchen.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

193 Beiträge seit 2006
vor 14 Jahren

Daher kann hier "this." beim Aufruf der Methode entfallen .....
Ich kenne aber auch keinen CodeStyle, der das explizit fordert

Bei den Coding Guidlines in meiner Firma ist dies gefordert.
z.B. wegen statischen Methoden. (siehe auch nachfolgendes Zitat von herbivore)

Für Methoden ist es ja dann eindeutig, da es keine lokalen Methoden gibt.
nein, denn es gibt statische Methoden. Deshalb ist es ohne this bzw. ohne den Klassennamen vor Methoden für den Leser, der nur die Aufrufstelle sieht, auch nicht eindeutig, welche Art von Methode gemeint ist.

Oder andersherum gesehen: Auch bei Variablen ist auch ohne this immer eindeutig definiert, was gemeint ist. Wäre es nicht eindeutig definiert, könnte der Compiler ja keinen Code erzeugen.

Das stimmt schon, aber durch ein this wird dies imho beim lesen sofort ersichtlich.

Davon abgesehen halte ich es für ungünstig, sich darauf zu verlassen, dass alle Variablen, die nicht mit this gekennzeichnet sind, keine Membervariablen sind, denn this ist schnell mal vergessen und der Compiler meckert dann ja gerade nicht.

So etwas lässt sich aber mit anderen Tools; z.B. dem StyleCop von MS überprüfen.

Was mich wieder dazu führt, dass man this nur an den Stellen verwenden sollte, wo es sich nicht vermeiden lässt.

Ich folge da dem genauen gegenteil. Zugriff auf instanz-Ebene nur über this; wie oben schon gesagt, ich finde das es den Code leichter lesbar macht, da ich immer genau sehe, auf was der Zugriff erfolgt.

Gruß Jake

5.299 Beiträge seit 2008
vor 14 Jahren

Um den Themenstarter vollends zu verwirren, möchte ich noch anführen, dass mit this auch Indexer deklariert werden, und auch Extension-Methods.

Aber erst in späteren Kapitels 😉

Ah, und im Constructor kann man mit this eine andere Constructor-Überladung aufrufen

Der frühe Apfel fängt den Wurm.

U
1.688 Beiträge seit 2007
vor 14 Jahren

Hallo,

Ich folge da dem genauen gegenteil. Zugriff auf instanz-Ebene nur über this; wie oben schon gesagt, ich finde das es den Code leichter lesbar macht, da ich immer genau sehe, auf was der Zugriff erfolgt.

Es ist allerdings unsinnig, wenn es mal so und mal so gemacht wird (s. Beispiel im Ausgangspost). Wenn also "nach Gefühl" entschieden wird, hier ist es mit "this." lesbarer, dort nicht. Dann wird's für andere weniger lesbar.
Wenn schon, dann konsequent überall. Eine Ungleichbehandlung stört.

H
116 Beiträge seit 2008
vor 14 Jahren

Um den Themenstarter vollends zu verwirren, möchte ich noch anführen, dass mit this auch Indexer deklariert werden, und auch Extension-Methods.

Vergiss bitte nicht die Verwendung bei Extensions. 😉

N
nodesperado Themenstarter:in
2 Beiträge seit 2010
vor 14 Jahren
Danke für die vielen Antworten

Hi Leute,

vielen Dank für eure Zahlreichen Antworten. Meine Frage wurde damit mehr als genügend beantwortet.

MfG, nodesperado