Initialisierung von Variablen: Direkt oder im Konstruktor? [Duplikat]

7

In den meisten Fällen sehe ich die Art und Weise, wie eine Variable wie diese initialisiert wird.

%Vor%

Aus meiner Sicht ist dies die allgemeinste Art, eine Variable zu initialisieren. Der meiste Code in Büchern, Blogs und auch internen Implementierungen von .NET entspricht meinem Beispiel.

Kürzlich habe ich Leute gesehen, die die Initialisierung direkt gemacht haben, also ohne den Wert im Konstruktor zu setzen.

%Vor%

Es besteht kein Unterschied, ob eine Variable initialisiert und deklariert oder die Variable im Konstruktor initialisiert wird.

Wo liegen neben den Best Practices und der Länge der Codezeilen die Vorteile der direkten Initialisierung einer Variablen und gibt es feine Unterschiede?

    
System.Data 29.12.2012, 16:37
quelle

6 Antworten

15

In einigen Fällen gibt es einen möglicherweise signifikanten Unterschied.

Instanzinitialisierer werden ausgeführt, bevor der Basisklassenkonstruktor ausgeführt wird. Wenn also der Basisklassenkonstruktor virtuelle Methoden aufruft, die in der abgeleiteten Klasse außer Kraft gesetzt werden, sieht diese Methode den Unterschied. Normalerweise sollte dies jedoch kein merklicher Unterschied sein, da das Aufrufen virtueller Methoden in einem Konstruktor fast immer eine schlechte Idee ist.

Wenn Sie die Variable zum Zeitpunkt der Deklaration initialisieren, wird deutlich, dass der Wert nicht von irgendwelchen Konstruktorparametern abhängt. Auf der anderen Seite hilft es, die gesamte Initialisierung zusammen zu halten, IMO. Ich würde versuchen , um sicherzustellen, dass wo immer möglich, wenn Sie mehrere Konstruktoren haben, sie alle delegieren zu einem "Master" -Konstruktor, der alle "echte" Initialisierung tut - was bedeutet, dass Sie nur diese Zuordnungen setzen Ein Ort auf jeden Fall.

Beispielcode, um den Unterschied zu demonstrieren:

%Vor%     
Jon Skeet 29.12.2012, 16:49
quelle
4

Ich kenne keine feinen Unterschiede. Normalerweise setze ich gerne alle Initialisierungen in den Konstruktor, weil ich denke, dass dadurch der Code lesbarer wird. Aber das ist eher eine Stilwahl und persönliche Vorliebe. Ich habe nichts von einem technischen Grund gehört, um es auf die eine oder andere Weise zu rechtfertigen. Ich bezweifle, dass es Auswirkungen auf die Leistung hat.

Konstanten, die statisch und endgültig sind, sind eine andere Sache. Ich initialisiere diese in-line.

    
duffymo 29.12.2012 16:40
quelle
4

Wenn eine Instanz erstellt wird, werden alle Variablen, die bei der Deklaration initialisiert werden, initialisiert, bevor der Konstruktor ausgeführt wird. Wenn Sie nicht auf diese Variablen zugreifen oder ihre Werte im Konstruktor selbst verwenden, gibt es keinen funktionalen Unterschied zwischen den beiden Methoden.

    
Jeff French 29.12.2012 16:41
quelle
2

Für Ihr einfaches Beispiel ist es einfach eine Frage des Stils.

Es gibt feine Unterschiede, wenn Vererbung beteiligt ist. Für Feldinitialisierer ist die Reihenfolge der Ausführung beispielsweise abgeleitete Klassenfeldinitialisierer, Basisklassenfeldinitialisierer, Basisklassenkonstruktor, abgeleitete Klassenkonstruktoren.

Nehmen Sie dieses Beispiel:

%Vor%

Es druckt:

  • DerivedInitializer
  • BaseInitializer
  • Basisctor
  • Abgeleitetes ctor
mike z 29.12.2012 16:51
quelle
2

lässt uns sagen, dass wir den folgenden Code unter release & amp; optimierte Builds

%Vor%

Die IL-Anweisung für Class Test1

%Vor%

Die IL-Anweisung für Class Test2

%Vor%

ist sehr offensichtlich, dass beide Klassen dieselbe Anzahl von IL-Anweisungen haben, das einzige diff ist

Die Variable

wird vor dem Aufruf von :: ctor () in Class Test1 initialisiert; und Die Variable wird nach dem Aufruf von :: ctor () in Class Test2;

initialisiert

ANMERKUNG : Leistungsmäßig wird die Klasse die gleiche Leistung erbringen, da sie die gleichen Nummern & amp; Art der IL-Anweisung, nur diese Reihenfolge der Ausführung von IL-Anweisung ist anders

    
PaRiMaL RaJ 29.12.2012 17:08
quelle
0
%Vor%

in der Klasse Test1 für jede Objektinstanz wird myIntToInitalize auf 10 gesetzt, aber nicht auf Klasse Test2, wenn Sie den Konstruktor aufrufen, der 1 Parameter benötigt.

    
Hendrik T 29.12.2012 16:54
quelle

Tags und Links