Initialisieren von Klassenfeldern in der Felddefinition oder im Klassenkonstruktor

8

Ich habe eine Klasse mit einem Feld, das initialisiert werden muss, wenn das Objekt initialisiert wird, z. B. eine Liste, die erstellt werden muss, bevor Objekte hinzugefügt / entfernt werden können.

%Vor%

Was ist der Unterschied zwischen diesen beiden Klassen, und warum würden Sie eine Methode gegenüber der anderen wählen?

Normalerweise setze ich das Feld im Konstruktor, wie in MyClass1, weil ich es einfacher finde, an einer Stelle nachzusehen, was alles passiert, wenn das Objekt instanziiert wird, aber ob es einen Fall gibt ist es besser, ein Feld direkt wie in MyClass2 zu initialisieren?

    
Eric Anastas 21.07.2009, 03:45
quelle

7 Antworten

5

Die ILs, die vom C # -Compiler (VS2008 sp1) ausgegeben werden, sind in beiden Fällen fast gleichwertig (sogar in Debug- und Release-Builds).

Wenn Sie jedoch parametrisierte Konstruktoren hinzufügen müssen, die List<MyOtherClass> als Argument verwenden , wird es anders sein (besonders, wenn Sie eine erheblich große Anzahl von Objekten mit solchen Konstruktoren erstellen).

Sehen Sie sich die folgenden Beispiele an, um die Unterschiede zu sehen (Sie können & VS in VS kopieren und so erstellen, dass ILs mit Reflektor angezeigt werden oder ILDASM ).

%Vor%

Hinweis: Beim Wechsel zu Release build habe ich kein Optimierungs-Flag geändert.

    
Chansik Im 21.07.2009, 04:59
quelle
3

Es gibt einen Unterschied:

  

Felder werden sofort initialisiert   vor dem Konstruktor für das Objekt   Instanz wird aufgerufen, also wenn die   Konstruktor weist den Wert von a zu   Feld wird ein beliebiger Wert überschrieben   während der Felddeklaration gegeben. Von   MSDN :

    
chikak 21.07.2009 05:34
quelle
3

Verhaltensweise sollten beide identisch sein.
Was Sie jedoch in Betracht ziehen möchten, ist ein Edge-Case IL - Aufblähen . Die IL für die Feldinitialisierer wird an die Spitze jedes Ctors eingefügt. Und daraus folgt, dass, wenn Sie viele Feldinitialisierer und viele überladene ctors haben, derselbe Abschnitt von IL dem ctor overload IL vorangestellt wird. Daher kann die Gesamtgröße Ihrer Assembly im Vergleich zu dem Fall, in dem Sie die Verkettung eines Konstruktors verwenden oder an eine allgemeine Initialize() -Funktion delegieren (wobei die wiederholte IL ein Methodenaufruf wäre), zunehmen. Daher wären Feldinitialisierer für dieses spezifische Szenario eine relativ schwächere Wahl.

Sie können dies mit reflector in der Binärdatei für dieses Code-Snippet überprüfen

%Vor%     
Gishu 21.07.2009 06:06
quelle
2

Bei der Initialisierung in einem Konstruktor würde ich denken, dass es einfacher wäre, Ausnahmen zu fangen und zu behandeln, wenn dies notwendig ist.

    
Stan R. 21.07.2009 04:13
quelle
1

In MyClass1 konnte jemand den Konstruktor überschreiben und Probleme verursachen.

    
eschneider 21.07.2009 05:22
quelle
0

Die Codes sind äquivalent, weil der Compiler in jedem Konstruktor die Initialisierung in den zweiten Fall setzt. Der Vorteil des zweiten Falls ist, dass der Programmierer nicht denkt, Felder zu initialisieren, wenn er nach dem Jahr des Schreibens dieser Klasse einen neuen Konstruktor hinzufügt:)

    
Arsen Mkrtchyan 21.07.2009 03:52
quelle
0

In c # gibt es praktisch keinen Unterschied zwischen Ihren beiden Beispielen. Entwickler neigen jedoch dazu, ihre Felder im Konstruktor zu initialisieren, weil sie weniger fehleranfällig sind.

    
Francis B. 21.07.2009 03:54
quelle