wake-up-neo.com

Was ist der Unterschied zwischen einem Objektinitialisierer und einem Konstruktor?

Was sind die Unterschiede zwischen den beiden und wann würden Sie einen "Objektinitialisierer" über einen "Konstruktor" und umgekehrt verwenden? Ich arbeite mit C #, wenn das wichtig ist. Ist die Objektinitialisierungsmethode auch spezifisch für C # oder .NET?

159
Pete

Objektinitialisierer wurden in C # 3 hinzugefügt, um die Konstruktion von Objekten zu vereinfachen, wenn Sie ein Objekt verwenden.

Konstruktoren werden mit 0 oder mehr Parametern ausgeführt und zum Erstellen und Initialisieren eines Objekts verwendet, bevor die aufrufende Methode das Handle für das erstellte Objekt erhält. Beispielsweise:

MyObject myObjectInstance = new MyObject(param1, param2);

In diesem Fall wird der Konstruktor von MyObject mit den Werten param1 Und param2 Ausgeführt. Diese werden beide verwendet, um das neue MyObject im Speicher zu erstellen. Das erstellte Objekt (das mit diesen Parametern eingerichtet wird) wird zurückgegeben und auf myObjectInstance gesetzt.

Im Allgemeinen wird empfohlen, dass ein Konstruktor die erforderlichen Parameter benötigt, um ein Objekt vollständig einzurichten, damit es unmöglich ist, ein Objekt in einem ungültigen Zustand zu erstellen.

Es gibt jedoch häufig "zusätzliche" Eigenschaften, die festgelegt werden können, jedoch nicht erforderlich sind. Dies könnte durch überladene Konstruktoren geschehen, führt jedoch dazu, dass viele Konstruktoren vorhanden sind, die unter den meisten Umständen nicht unbedingt nützlich sind.

Dies führt zu Objektinitialisierern - Mit einem Objektinitialisierer können Sie Eigenschaften oder Felder für Ihr Objekt festlegen , nachdem es erstellt wurde , aber , bevor Sie es von etwas anderem verwenden können. Beispielsweise:

MyObject myObjectInstance = new MyObject(param1, param2)
{
    MyProperty = someUsefulValue
};

Dies verhält sich ungefähr so, als ob Sie dies tun:

MyObject myObjectInstance = new MyObject(param1, param2);
myObjectInstance.MyProperty = someUsefulValue;

In Umgebungen mit mehreren Threads kann die Atomizität des Objektinitialisierers von Vorteil sein, da verhindert wird, dass sich das Objekt in einem nicht vollständig initialisierten Zustand befindet ( siehe diese Antwort für weitere Einzelheiten) - entweder null oder initialisiert, wie Sie es beabsichtigt haben.

Darüber hinaus sind Objektinitialisierer einfacher zu lesen (insbesondere, wenn Sie mehrere Werte festlegen), sodass Sie den gleichen Vorteil wie bei vielen Überladungen des Konstruktors erzielen, ohne dass die API für diese Klasse durch viele Überladungen kompliziert werden muss.

225
Reed Copsey

Ein Konstruktor ist eine definierte Methode für einen Typ, der eine bestimmte Anzahl von Parametern akzeptiert und zum Erstellen und Initialisieren eines Objekts verwendet wird.

Ein Objektinitialisierer ist Code, der auf einem Objekt nach einem Konstruktor ausgeführt wird und verwendet werden kann, um eine beliebige Anzahl von Feldern für das Objekt auf bestimmte Werte zu setzen. Die Einstellung dieser Felder erfolgt nach der Konstruktor wird aufgerufen.

Sie würden einen Konstruktor ohne die Hilfe eines Objektinitialisierers verwenden, wenn der Konstruktor den Anfangszustand des Objekts ausreichend festlegt. Ein Objektinitialisierer muss jedoch in Verbindung mit einem Konstruktor verwendet werden. Die Syntax erfordert die explizite oder implizite Verwendung (VB.Net und C #) eines Konstruktors, um das ursprüngliche Objekt zu erstellen. Sie würden einen Objektinitialisierer verwenden, wenn der Konstruktor das Objekt nicht ausreichend für Ihre Verwendung initialisiert und dies mit einigen einfachen Feld- und/oder Eigenschaftssätzen tun würde.

44
JaredPar

Wenn Sie das tun

Person p = new Person { Name = "a", Age = 23 };

das macht ein Objektinitialisierer im Wesentlichen:

Person tmp = new Person(); //creates temp object calling default constructor
tmp.Name = "a";
tmp.Age = 23;
p = tmp;

Nun erleichtert dies das Verhalten wie this . Es ist wichtig zu wissen, wie Objektinitialisierer funktionieren.

27
nawfal

Wenn Sie Eigenschaften haben, die für Ihr Objekt festgelegt werden MÜSSEN, damit es ordnungsgemäß funktioniert, besteht eine Möglichkeit darin, nur einen einzigen Konstruktor verfügbar zu machen, für den diese obligatorischen Eigenschaften als Parameter erforderlich sind.

In diesem Fall können Sie Ihr Objekt nicht erstellen, ohne diese obligatorischen Eigenschaften anzugeben. So etwas kann von Objektinitialisierern nicht erzwungen werden.

Objektinitialisierer sind eigentlich nur eine "Syntax-Annehmlichkeit", um anfängliche Zuweisungen zu verkürzen. Schön, aber nicht wirklich sehr funktional relevant.

Marc

14
marc_s

Ein Konstruktor ist eine Methode, die (möglicherweise) Parameter akzeptiert und eine neue Instanz einer Klasse zurückgibt. Es kann eine Initialisierungslogik enthalten. Unten sehen Sie ein Beispiel für einen Konstruktor.


public class Foo
{
    private SomeClass s;
    public Foo(string s)
    {
       s = new SomeClass(s);
    }
}

Betrachten Sie nun das folgende Beispiel:


public class Foo
{
    public SomeClass s { get; set; }
    public Foo() {}
}

Sie könnten dasselbe Ergebnis wie im ersten Beispiel mit einem Objektinitialisierer erzielen, vorausgesetzt, Sie können mit dem folgenden Code auf SomeClass zugreifen:


new Foo() { s = new SomeClass(someString) }

Wie Sie sehen, können Sie mit einem Objektinitialisierer Werte für öffentliche Felder und öffentliche (einstellbare) Eigenschaften angeben, während die Erstellung ausgeführt wird. Dies ist insbesondere dann hilfreich, wenn der Konstruktor keine Überladung bereitstellt, die bestimmte Felder initialisiert. Beachten Sie jedoch, dass Objektinitialisierer nur syntaktischer Zucker sind und sich nach dem Kompilieren nicht wirklich von einer Abfolge von Zuweisungen unterscheiden.

4
em70