Feld vor Aufruf von Basiskonstruktor initialisieren
-
public constructor() : base(null) { this.field = -1; }
Der Ablauf dürfte klar sein. Erst wird base(object) ausgeführt und dann this.field -1 zugewiesen. Wie kann ich erreichen, dass this.field vor dem Aufruf von base(object) -1 zugewiesen wird? Ich weiß, dass das funktioniert, aber leider nicht wie.
-
flub schrieb:
public constructor() : base(null) { this.field = -1; }
Der Ablauf dürfte klar sein. Erst wird base(object) ausgeführt und dann this.field -1 zugewiesen. Wie kann ich erreichen, dass this.field vor dem Aufruf von base(object) -1 zugewiesen wird? Ich weiß, dass das funktioniert, aber leider nicht wie.
Garnicht. Ich geh mal davon aus, dass field in der aktuellen Klasse definiert ist und deshalb erst erzeugt wird, nach dem alle Basisklassenkonstruktoren aufgerufen wurden.
-
Doch es geht, ich habe MSIL-Code vorliegen, bei dem das so ist. Es geht in diesem speziellen Fall, weil nicht base() explizit aufgerufen wird, sondern base(object). Also ein anderer Konstruktor der Basisklasse. Ich dachte erst daran, dass man base(null) irgendwie im Rumpf des Konstruktors aufrufen könnte, aber dann würde die vorgegebene Vererbung nicht mehr funktionieren. base(null) muss also direkt nach dem ':' geschrieben werden. Dann dachte ich, dass es vielleicht sowas wie in C++ geben könnte:
[C++]
constructor() : field(42), field2(2.5f)Aber irgendwie komme ich nicht auf einen Nenner...
-
Nochmal: Es geht NICHT. Erst nach dem alle Basisklassenkonstruktoren abgearbeitet wurden, wird Speicher für die Instanzvariablen angelegt.
-
Und als würdest Du dann z.B. folgendes Bezeichnen?
.method assembly hidebysig specialname rtspecialname instance void .ctor(class System.Windows.Forms.MenuItem baseItem, valuetype System.Windows.Forms.MenuMerge mergeType, int32 mergeOrder, valuetype System.Windows.Forms.Shortcut shortcut, bool showShortcut, string caption, class [mscorlib]System.EventHandler onClick, class [mscorlib]System.EventHandler onPopup, class [mscorlib]System.EventHandler onSelect, class System.Windows.Forms.DrawItemEventHandler onDrawItem, class System.Windows.Forms.MeasureItemEventHandler onMeasureItem) cil managed { // Codegröße 124 (0x7c) .maxstack 3 IL_0000: ldarg.0 IL_0001: ldnull IL_0002: stfld object System.Windows.Forms.MenuItem/MenuItemData::userData IL_0007: ldarg.0 IL_0008: call instance void [mscorlib]System.Object::.ctor()
this.userData wird hier null zugewiesen, noch bevor base() aufgerufen wird.
-
Kannst mir gerne bescheid geben, wenn du es in C# geschafft hast
-
interpreter schrieb:
Erst nach dem alle Basisklassenkonstruktoren abgearbeitet wurden, wird Speicher für die Instanzvariablen angelegt.
Ich kann im Basisklassen-Konstruktor eine virtuelle Funktion aufrufen, die in der abgeleiteten Klasse überschrieben wurde. Dort werden Member der abgeleiteten Klasse initialisiert, obwohl der Konstruktor der Basisklasse noch nicht abgearbeitet wurde. Ist das ein Widerspruch?
-
Nicht schlecht, daran habe ich gar nicht gedacht.
-
Nicht ganz. Du kannst nicht vor der Initialisierung irgendeine Methode aufrufen, selbst der Konstruktor wird erst nach der Initialisierung aufgerufen.
Ja, du kannst im Konstruktor der Basisklasse über diesen Umweg Werte an die Member der abgeleiteten Klasse zuweisen.
Aber: Schon vorher werden die Elemente initialisiert.class Foo { int member = 2; // DAS ist eine Initialisierung. }
-
Richtig. Alles, was du in der überschriebenen Methode machst sind dann nur noch Zuweisungen an bereits initialisierte Variablen.
-
Ich frage mich, was passiert, wenn man zur Initialisierung eine virtuelle Methode benutzt...
-.-EDIT: Hat sich erübrigt. Man kann zur Initialisierung keine Methoden mit dem eigenen Objekt benutzen.
Es ist also wirklich nicht möglich, vor der Initialisierung irgendwelchen Code auszuführen, der das eigene Objekt verändert oder ausliest.
-
interpreter schrieb:
Kannst mir gerne bescheid geben, wenn du es in C# geschafft hast
Ich hab's geschafft:
class Foo { int bar = 42; }
Jupp, so einfach ist's. Nun wird bar im Foo-Konstruktor 42 zugewiesen, noch bevor der Basisklassen-Konstruktor aufgerufen wird (wie im MSIL-Beispiel weiter oben im Thread).
-
das ist jetzt aber schon alt.
-
*hmpf* Hab ich gar nicht bemerkt.