Foundations for Professionals .NET Professionals im Profil guide to C# guidgen.de

Blog

Nutze den Augenblick
und teile der Welt mit, was Du zu sagen hast.

this oder kein this

Freitag, 1. Januar 2010, 09:37 Uhr
Permalink | Kommentare (6) | Kommentare als RSSRSS

Am 13. Oktober 2008 haben Peter Bucher und ich unter dem Titel Noch Fragen, Bucher? Ja, Roden! angekündigt, jeweils zum ersten eines jeden Monats einen Kommentar zu einem vorab gemeinsam gewählten Thema verfassen zu wollen. Bisher sind in dieser Reihe folgende Kommentare erschienen:

Heute, am 1. Januar 2010, ist es nun wieder so weit, und unser Thema für diesen Monat lautet:

this oder kein this

So wohl Peter wie auch ich haben uns unabhängig voneinander im Vorfeld unsere Gedanken gemacht, wie wir diesem Thema gegenüberstehen. Peters Kommentar findet sich zeitgleich in seinem Blog, folgend nun mein Kommentar zu diesem Thema:

Zumeist sind Schlüsselwörter innerhalb einer Programmiersprache mit einer eindeutigen Semantik belegt; auch C# stellt keine Ausnahme dieser Regel dar. Jedoch gilt dies zumindest in C# wohlgemerkt nicht für alle Schlüsselwörter, denn einige haben – je nach Kontext – verschiedene Bedeutungen.

Ein bekanntes und weit verbreitetes Beispiel hierfür ist das Schlüsselwort using, das so wohl als Direktive wie auch als Anweisung verwendet werden kann:

  • Als Direktive dient es zunächst dazu, andere Namensräume bekannt zu machen, so dass die darin enthaltenen Typen ohne Angabe ihres vollqualifizierten Namens genutzt werden können.
  • Die Direktive dient zusätzlich jedoch auch der Bildung von Aliasnamen, wobei dies wiederum so wohl für Namensräume wie auch für einzelne Typen möglich ist.
  • Als Anweisung schließlich definiert using in Verbindung mit der IDisposable-Schnittstelle einen Gültigkeitsbereich, an dessen Ende automatisch die Dispose-Methode des gekapselten Objekts aufgerufen wird.

Doch nicht nur using ist mit verschiedenen Bedeutungen belegt – ein weiterer Kandidat mit zahlreichen Varianten ist das this-Schlüsselwort:

  • In Verbindung mit Konstruktoren dient das this-Schlüsselwort dazu, den Aufruf an einen überladenen Konstruktor der gleichen Klasse weiterzuleiten.
  • Mit this ist es zudem möglich, Indexer zu definieren – also Eigenschaften, die über keinen eigenen Namen verfügen, allerdings parametrisiert mit einem Index aufgerufen werden können.
  • Seit C# 3.0 dient this als Kennzeichner für Erweiterungsmethoden, indem mit Hilfe dieses Schlüsselworts festgelegt wird, welches Argument dem aufrufenden Objekt entspricht.
  • Schließlich dient this – wie bereits in C++ und Java – auch als Referenz auf das eigene Objekt. Auf diese Art kann auf Elemente der Klasse zugegriffen werden, deren Namen durch gleichnamige Parameter ansonsten ausgeblendet und damit nicht zugreifbar wären.

Im Gegensatz zu using, dessen Angabe immer erforderlich ist, kann this gegebenenfalls entfallen: Während seine Verwendung bei der Verkettung von Konstruktoren, Indexern und Erweiterungsmethoden obligatorisch ist, kann die Eigenreferenz entfallen – sofern der Name des betroffenen Elements nicht ausgeblendet wird.

Die Frage lautet allerdings, ob es sinnvoll ist, this in den optionalen Fällen zu streichen. Zunächst scheint es so, schließlich erspart man sich einige Zeichen zu tippen, zu lesen und vermeidet unnötige Redundanz. Auch ReSharper empfiehlt bei Verwendung der Standardeinstellungen, redundante this-Schlüsselwörter zu entfernen.

Neben diesen Vorteilen birgt das Entfernen von this jedoch auch einen essenziellen Nachteil: Es ist nicht mehr auf einen Blick ersichtlich, ob ein Zugriff auf ein Element des aktuellen Objekts stattfindet. So ist bei der Zeile

_foo = new Foo();

nicht klar, ob es sich um eine statisches Feld oder ein Instanzfeld handelt. Wird das Schlüsselwort this jedoch konsequent verwendet, ist auf den ersten Blick eindeutig, dass es sich um ein statisches Feld handelt, ansonsten müsste die Zeile nämlich

this._foo = new Foo();

lauten. Während diese Mehrdeutigkeit bei Feldern noch zu vertreten sein mag, wird es bei Eigenschaften bedeutend schwieriger: So bestehen für die Zeile

Foo.Bar();

bereits drei Möglichkeiten, welcher Aufruf sich dahinter verbirgt: Zum einen könnte Foo eine Eigenschaft sein, an der eine Methode namens Bar aufgerufen wird. Es ist jedoch nicht eindeutig, ob es sich bei der Eigenschaft um eine statische oder eine instanzbehaftete Eigenschaft handelt.

Neben diesen zwei Möglichkeiten könnte es zudem sein, dass Foo gar keine Eigenschaft, sondern eine statische Klasse bezeichnet, die ihrerseits wiederum eine Methode Bar() enthält.

Der Unterschied zwischen einer statischen Eigenschaft und einer statischen Klasse lässt sich ohne weiteres nicht auflösen – zumindest der erste Fall kann aber durch Verwendung von this explizit gemacht werden. Bei der Zeile

this.Foo.Bar();

ist nämlich auf den ersten Blick ersichtlich, dass eine Methode an einer Eigenschaft aufgerufen wird, die instanzbehaftet ist.

Diese Beispiele zeigen, dass die konsequente Verwendung von this durchaus ihren Teil zu einer besseren Verständlichkeit des Quellcodes beitragen kann.

Da Code in der Regel derart geschrieben wird, dass er für die Zukunft wie auch für andere Entwickler gut lesbar ist, kann es durchaus eine vernünftige Entscheidung sein, this generell zu verwenden – insbesondere auch in den redundanten Fällen, um die Semantik des Codes explizit zu machen.

Für welche Variante auch immer ein Entwickler beziehungsweise ein Team sich entscheidet, wichtig ist – wie so oft, wenn es um das Thema Coderichtlinien geht – dass die einmal getroffene Entscheidung konsequent eingehalten wird. Alles andere führt über kurz oder lang zu Missverständnissen.