| 

.NET C# Java Javascript Exception

2
Gleich bei der Deklaration?
public class D extends Dialog {
Button ok = new Button("OK");
...
}


Oder im Konstruktor bzw einer Methode aufgerufen im Konstruktor?
public class D extends Dialog{
Button ok;
pulic D(){
ok = new Button("OK");
}
}


Hat das einen Einfluß auf die Perfomance? Oder nur eine Frage des Stills? Macht es einen Unterschied wenn der Werte der Variable ein Objekt oder ein Literal ist?
11.09.2009
ermin 1,3k 2 7
11 Antworten
5
Hi, ganz klar im Konstruktor, denn dafür ist er da!
Das ganze hat den Hintergrund, dass wenn du zum Bsp. Class Objekte serialisierst bzw. deserialisierst ein sogananntes WakeUp stattfindet. Das Objekt wird also neu initialisiert und dann die Werte entsprechend gesetzt. Bei der Deklaration gabs da bei mir schonmal Probleme.

Edit:
Es mag sein, dass es in .net egal ist wo man was hinschreibt, weil der Code ja ehh nochmal compiliert wird. Allerdings wenn man in Sprachen schreibt die nur interpretiert werden, dann sollte man es "richtig" setzen. Da .net es nach dem compilieren in den Konstruktor setzt, bestätigt dies mich, dass ich es immer in den Konstruktor setze (in allen Sprachen).

Grüßle
11.09.2009
Scout 1,4k 2 8
Scout 1,4k 2 8
Serialisierung ist ein gutes Argument
klaus_b 11.09.2009
Bist du sicher dass (in .net) das Problem wegen der Deklaration war?
gfoidl 11.09.2009
@gfoidl: Nein, hantiere hier auch mit dutzend anderen Sprachen. Daher habe ich mir angewöhnt es richtig zu schreiben und nicht nach Geschmack ;-)
Scout 11.09.2009
Dein Edit ist ein guter Hinweis.
gfoidl 11.09.2009
6
In .net gibt es keinen Unterschied denn der Compiler erstellt den Code so dass Felder mit Standardwert nur im Konstruktor initiert werden.

Dieser Code
class Foo
{
private string _name = "gfoidl";
private int _alter;

public Foo()
{
_alter = 27;
}
}

Der Reflektor zeigt den Konsturktor so an (es kann auch der IL mit MSIL angeschaut werden - gleiches Ergebnis):
public Foo()
{
this._name = "gfoidl";
this._alter = 0x1b;
}


Insofern ist es eine geschmacksache.
11.09.2009
gfoidl 9,4k 3 5
Da ja nun zweifelsfrei geklärt ist, dass .net keine Sprache ist, halte ich diese Aussage in dieser Allgemeinheit für gewagt. Oder lässt sich keine .net-aufsetzende Sprache implementieren, die sich hier anders verhält?
sml-ki 11.09.2009
Wenn sie dem Standard von CIL (der Intermediate Language in der alle Sprachen die auf .net aufsetzen kompiliert werden) genügt dann nicht.
gfoidl 11.09.2009
2
Ich denke, dass ist eher eine Frage der Verwendung der Variablen.
Wenn du sie, die Variable, nur intern benötigst klar bei der Deklaration.
Willst du die Variable zur Verfügung stellen must du entscheiden ob sie bei der Instanziierung belegt werden muss. Dann natürlich im Konstruktor oder einer Methode die im Konstruktor verarbeitet wird.

Macht es einen Unterschied wenn der Werte der Variable ein Objekt oder ein Literal ist?
Der Wert der Variablen ist ja Typ-gebunden :-)
11.09.2009
klaus_b 1,6k 3 7
1
gfoidl hat für c# schon das Wesentliche gesagt. Der Unterscheid entsteht dann, wenn es mehrere Konstruktoren gibt. Die Initialisierung bei der Deklaration gilt dann für alle Konstruktoren. So kann man, wenn man es mag, die Initialisierung die allen Konstruktoren gemeinsam ist herausziehen.
11.09.2009
pjacobi 1,1k 2 7
1
Wenn man die Membervariable direkt initialisiert, also die erste Schreibweise verwendet,
gilt dies für ALLE Konstruktoren.

Ich halte diesen Weg für sicherer, da auch weitere/neue Konstruktoren davon profitieren.
Und man muß weniger Code schreiben wenn mehrere Konstruktoren vorhanden sind.
Aber meines Wissens geht das nur für Java und C#, aber nicht für C++.

Ich benutze eine - eigentlich überflüssige - Definition
Button ok = null
um anzudeuten, dass im Konstruktur bzw. in den Konstrukturen etwas besonderes passiert.
11.09.2009
stefan.bachert 395 4
1
in Java belege ich Membervariablen normalerweise im Klassenkontext mit null oder eben -1 bei ints/longs vor, um eben zu zeigen (die werden auf jeden Fall noch angefasst)
Die Initalisierung muss dann eben im Konstruktor beziehungsweise in dort aufgerufenen Klassen vorgenommen werden.
Was man natürlich beachten sollte ... wurde glaube ich noch nicht genannt.
"public static final" variablen sollten natürlich nicht erst im Konstruktor vorbelegt werden :)

In ganz seltenen Fällen, wo Werte von Variablen schon VOR dem super()-Aufruf für die Vaterklasse bekannt sein müssen, können diese im static Klassenkontext vorbelegt werden.
11.09.2009
Vayu 656 1 3
Vayu 656 1 3
Wenn die Antwort auf Java abzielt erwähne das. In anderen Sprachen/Plattformen wie .net kann keine Initialisierung mit von dort aufgerufenen Klassen vorgenommen werden.
gfoidl 11.09.2009
vielleicht warst du ja zu schnell :) ich hatte das noch direkt danach reineditiert
Vayu 11.09.2009
0
Nicht-initialisierte Variablen sind eine haeufige Fehlerquelle.
11.09.2009
knivil 209 2
1
In .net werden Felder mit default(T) belegt. D.h. null für Referenztypen und 0 für numerische Werttypen. Bei Strukturen werden die Felder entsprechend ihres Typ belegt.
gfoidl 11.09.2009
Er hatte aber auch C++ als Themenbereich angegeben. Deswegen ...
knivil 11.09.2009
Ich weiß. Deswegen hab ich in meiner Antwort auch die Sprache/Plattform erwähnt. Mein obiger Kommentar bezieht sich auch auf .net - damit keine Unklarheiten entstehen.
gfoidl 11.09.2009
0
Die direkte Zuweisung von Attributen findet bereits vor einem Konstruktor-Aufruf statt und stellt somit eine Default-Belegung von Attributen dar. Prinzipiell kann man diese Arbeit auch von Konstruktoren erledigen lassen, dann aber muss sie in jedem Konstruktor erfolgen.

Die Belegung im Konstruktor ist natürlich flexibler, weil sie a) parametrisiert und b) auf checked Exceptions reagieren kann.

Performance spielt jedenfalls keine Rolle.
11.09.2009
sml-ki 49 2
In .net gibt es keinen Unterschied! Und Attribute können in .net nicht zur Laufzeit belegt werden - Attribute sind was anderes. Das was du meinst sind Felder!
gfoidl 11.09.2009
Für das Crossposting des Fragenden fühle ich nicht verantwortlich, ich bin über das Thema "Java" eingestiegen. Dass .net eine Sprache ist, wusste ich allerdings nicht.
sml-ki 11.09.2009
.net ist eine Plattform keine Sprache (das wurde von mir nie so bezeichnet).

Wenn mehrere Sprachen von der Frage zugelassen sind warum deklariert man nicht die Sprache auf die sich die Antwort bezieht?
gfoidl 11.09.2009
0
IMHO ist das Problem nur etwas Ausführlicher zu beantworten:
Ich finde die Initialisierung von Variablen sollte nach Möglichkeit immer an einer Stelle erfolgen und zwar einheitlich an der selben Stelle. Damit wird bereits gesagt, dass die Variablen nicht im sogenannten Konstruktor direkt initialisiert werden können (ich kann ja mehrere davon haben). Direkt bei der Deklaration macht aber unter Umständen Probleme. Zugriff auf Variablen untergeordneter Klassen...
Somit bleibt aus meiner Sicht nur eine einheitliche Methode, die die gesamte Initialisierung der Instanz vornimmt => eine 'protected void initialize ()'.

@sml-ki
> Die direkte Zuweisung von Attributen findet bereits vor einem Konstruktor-Aufruf statt
Ja aber nur die Variablen der eigenen Instanz; nicht jedoch der Abgeleiteten Klassen. Wird dann - zum Beispiel über einen abstrakten Accessor - auf derartige Variablen zugegriffen, dann knallt es...
11.09.2009
NoComment 151 1 2
Von wo wird denn die 'protected void initialize ()' augerufen? Wenn es nicht im Kontext des Konstruktors geschieht ist die ganze Konstruktor-Sache doch umsonst ;)
gfoidl 11.09.2009
1
"..(ich kann ja mehrere davon haben)" Na und?!? In .NET hast du die Möglickeit bei Konstruktorüberladungen immer einen bestimmten Konstruktor explizit zu initialisieren etwa:
Foo(string test, AnyStatus status){}
Foo(string test):this(test, AnyStatus.Default){}
Selbst wenn ich in einer abgeleiteten Klasse nur den Konstruktor mit einem Parameter initilisiere, wird immer die Überladung auch richtig initialisiert.
klaus_b 11.09.2009
0
In Code Commplete (unbeding lesenswert) wird vorgeschlagen vor der ersten Verwendung zu initalisiern. Ansonsten ist natürlich der Konstruktor der "richtige" Platz...
07.10.2009
FDominicus 139 1 1
0
Grundsätzlich im Konstruktor. Bei Objekten, die teuer sind, eventuell lazy initialization über den entsprechenden Getter.
09.02.2011
oopexpert 455 1 8

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH