2008-12-03 9 views
15

Hin und wieder stoße ich auf die Syntax, die ich vorher gesehen, aber nie benutzt habe. Dies ist eine dieser Zeiten.: Diese (foo) Syntax in C# -Konstruktoren?

Kann jemand den Zweck von ": this" oder ": base" nach einer C# -Konstruktormethode erklären?

Zum Beispiel:

public MyClass(SomeArg arg) : this(new SomethingElse(), arg) 
{ 
} 

Mein Bauchgefühl ist, dass es ein Standardargument auf einem anderen Konstruktor-Methode zur Karte verwendet wird.

Antwort

17

Sie haben grundsätzlich recht. this() ruft einen Konstruktor für die aktuelle Instanz auf, base() ruft den Konstruktor des Supertyps für die aktuelle Instanz auf. Sie werden im Allgemeinen verwendet, um Überladungen von Konstruktoren zu behandeln, sodass Sie zusätzliche Optionen hinzufügen können, ohne dass die Dinge in eine separate Methode aufgeteilt werden müssen.

4

Sie haben Recht.

: base (...) ruft einen Konstruktor der Basisklasse auf.

: Diese (...) ruft einen anderen Konstruktor der definierenden Klasse auf. Meistens funktioniert es nur als Fassade.

3

Jeder Konstruktor in einer .NET-Klasse stellt sicher, dass ein Konstruktor in der Klasse, von der er erbt, ebenfalls aufgerufen wird.

Also, wenn Sie die folgenden Klassen:

public class Base { } 
public class Something : Base { } 
public class Else : Something { } 

dann ein Konstruktor in Else, einen Konstruktor in etwas nennen, die auch einen Konstruktor in der Base nennen.

Der Konstruktor, der in einer Basisklasse aufgerufen wird (dh die, von der Sie abstammen), ist immer der parameterlose Konstruktor.

Wenn Sie keine haben oder diese überschreiben möchten, können Sie sie überschreiben, indem Sie die Basis angeben (einige Parameter hier). Dies wird den richtigen Konstruktor in der Basisklasse auswählen.

Sie können auch einen Konstruktor bitten, zuerst einen anderen Konstruktor in derselben Klasse auf derselben Ebene aufzurufen. Dies kann verwendet werden, um zu vermeiden, dass Konstruktorcode in mehreren Konstruktoren dupliziert wird. Schließlich rufen die aufgerufenen Konstruktoren einen Konstruktor in der Basisklasse auf.

Ich hoffe, das war verständlich.

19

Ihr Bauchgefühl ist richtig. Die Syntax wird benutzt in der gleichen Klasse ladenen Konstruktoren zu nennen:

public class Test 
{ 
    public Test() : this("Called from default constructor") { } 
    public Test(String msg) 
    { 
     Console.WriteLine(msg); 
    } 
} 

der folgende Code:

public static void Main(String[] args) 
{ 
    Test t1 = new Test(); 
    Test t2 = new Test("Called from Main function"); 
} 

Ausgänge der folgenden

Called from default constructor 
Called from main function

In ähnlicher Weise wird : base(someParams) verwendete Basis Konstruktoren nennen .

2

Genau. Der Aufruf von Constructor Chaining wird verwendet, um die Tatsache zu umgehen, dass C# keine Standardargumente ausführen kann.

Dies wird häufig in IoC verwendet.

2

Es ist so, wenn ich nicht irre:

public MyClass(SomeArg arg) : this(new SomethingElse(), arg) 

rufen

public MyClass(SomethingElse arg, SomeArg arg1) : base or this or nothing 

und das wird weitergehen, bis Sie eine Basis oder nichts bekam.

Wenn Sie base(....) haben, dann wird dieser Konstruktor, der den Basiskonstruktor mit den Parametern (falls vorhanden) angegeben hat, die wiederum an seine eigenen Konstruktoren (dasselbe Spiel) delegieren kann.

Wenn Sie nichts haben, wird der parameterlose Konstruktor der Basisklasse automatisch aufgerufen.

Nachdem Sie this(....) verwendet haben, wird der Konstruktor, der den Parametern entspricht, verwendet und sein Body wird ausgeführt - zusätzlich zum Rumpf des Konstruktors, der this(....) verwendet hat.

2

Ja, Sie haben Recht. Diese Syntax wird verwendet, damit Ihre Konstruktoren für Unterklassen explizit einen geeigneten benutzerdefinierten Basisklassenkonstruktor anstelle des Standardkonstruktors aufrufen. Das Schlüsselwort this in Ihrer Frage wird erklärt:

Eine weitere Verwendung des this-Schlüsselworts besteht darin, einen Konstruktor zum Aufrufen eines anderen zu zwingen, um redundante Elementinitialisierungslogik zu vermeiden.

in Pro C# 2005 und .NET 2.0-Plattform, 3rd Edition von Andrew Troelsen