Initialisierung der C # -Membervariable; beste Übung?
Ist es besser zum initialisieren von Klassenvariablen Deklaration
private List<Thing> _things = new List<Thing>();
private int _arb = 99;
oder in der default-Konstruktor?
private List<Thing> _things;
private int _arb;
public TheClass()
{
_things = new List<Thing>();
_arb = 99;
}
Ist es einfach eine Sache des Stils oder gibt es performance trade-offs, die eine oder andere Weise?
InformationsquelleAutor der Frage Steve Crane | 2008-11-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
In Bezug auf Leistung, es gibt keinen wirklichen Unterschied; Feld-Initialisierungen sind implementiert als Konstruktor-Logik. Der einzige Unterschied ist, dass die Feld-Initialisierungen geschehen, bevor ein "base"/"this-Konstruktor.
Konstruktor Ansatz kann verwendet werden, mit automatisch implementierten Eigenschaften (Feld-Initialisierungen können) - d.h.
Andere als das, ich Neige dazu, lieber die Feld-Initialisierer-syntax; ich finde es hält die Dinge lokalisiert - d.h.
Habe ich nicht auf die Jagd gehen nach oben und unten zu finden, wo es zugewiesen ist...
Die offensichtliche Ausnahme ist, wo Sie brauchen, um komplexe Logik oder befassen sich mit Konstruktor - Parameter-in diesem Fall Konstruktor-basierte Initialisierung ist der Weg zu gehen. Ebenso, wenn Sie haben mehrere Konstruktoren, wäre es besser für die Felder erhalten immer den gleichen Weg - so haben Sie ctors wie:
edit: als Randnotiz, beachten Sie, dass in den oben genannten, wenn es andere Felder (nicht gezeigt), die mit Feld-Initialisierungen, dann sind Sie nur direkt bei der Initialisierung im Konstruktor, Aufruf
base(...)
- d.h. diepublic Bar(string foo)
en. Der andere Konstruktor hat nicht ausführen-Feld-Initialisierungen, da Sie weiß, dass Sie fertig sind durch diethis(...)
en.InformationsquelleAutor der Antwort Marc Gravell
Eigentlich, Feld-Initialisierungen, wie Sie zeigen, ist eine praktische Abkürzung. Der compiler kopiert tatsächlich die Initialisierung code in den Anfang der Instanz-Konstruktor definieren Sie für Ihren Typ.
Dies hat zwei Implikationen: Erstens, jede Feld-Initialisierung code dupliziert wird in jedem Konstruktor und, zweitens, jede code, den Sie enthalten in Ihren Konstruktoren initialisieren-Felder auf bestimmte Werte, wird in der Tat re-ordnen Sie die Felder.
Also performance-Weise, und mit Bezug auf die kompilierte code-Größe, sind Sie besser dran, sich bewegenden Feld-Initialisierungen in Konstruktoren.
Auf der anderen Seite, die Auswirkungen auf die Leistung und code - 'aufblasen' wird in der Regel negligable, und die Feld-Initialisierer-syntax hat den wichtigen Vorteil der Verminderung der Gefahr, dass Sie vielleicht vergessen Initialisierung einiger Felder in einer Ihrer Konstruktoren.
InformationsquelleAutor der Antwort Tor Haugen
Eine wichtige Einschränkung mit Feld-Initialisierungen ist, gibt es keine Möglichkeit, wickeln Sie Sie in einem try-finally-block. Wenn eine Ausnahme geworfen wird in einem Feld-Initialisierer, keine Ressourcen zugeordnet wurden, die in früheren Initialisierungen wird aufgegeben werden; es gibt keine Möglichkeit, es zu verhindern. Andere Fehler in der Konstruktion behandelt werden können, wenn ungeschickt, indem er eine geschützte Basis-Konstruktor akzeptiert einen IDisposable durch die Referenz und zeigt es bei sich als seinen ersten Betrieb. Man kann dann vermeiden, den Aufruf der Konstruktor-außer durch factory-Methoden, die im Falle der Ausnahme Aufruf von Dispose für die teilweise erstellte Objekt. Dieser Schutz ermöglicht die Bereinigung von IDisposables erstellt, in der abgeleiteten Klasse Initialisierungen, wenn die main-Klasse Konstruktor fehlschlägt, nach der "Schmuggel" eine Referenz auf das neue Objekt. Leider gibt es keine Möglichkeit, einen solchen Schutz bieten, wenn ein Feld-Initialisierung schlägt fehl.
InformationsquelleAutor der Antwort supercat
Entweder Feld-Initialisierungen oder erstellen Sie eine Init () - Funktion. Das problem mit dem setzen diese Dinge in Ihrem Konstruktor ist, dass, wenn Sie jemals brauchen werden, um fügen Sie einen 2. Konstruktor, den Sie am Ende mit kopieren/einfügen der code (oder Sie übersehen es und am Ende mit nicht initialisierten Variablen).
Ich würde entweder initialisieren, wo Sie deklariert wurde. Oder haben die Konstruktor(en) Aufruf einer Init () - Funktion.
InformationsquelleAutor der Antwort GeekyMonkey
Für Instanz-Variablen, es ist weitgehend eine Sache des Stils (die ich lieber mit einem Konstruktor). Für statische Variablen, es ist ein Leistungsvorteil zu initialisieren inline (nicht immer möglich ist, natürlich).
InformationsquelleAutor der Antwort Kent Boogaart
Es ist wirklich bis zu Ihnen.
Ich habe oft zu initialisieren inline, weil ich nicht wie ein Konstruktor, wenn ich nicht wirklich brauchen (ich mag kleine Klassen!!!).
InformationsquelleAutor der Antwort Nico
Auf zusätzlichen Punkt zu den oben genannten - haben Sie immer einen Konstruktor bei der Implementierung von Klassen, die eine Implementierung. Wenn Sie nicht erklären, man dann die Standard-instructor ist abgeleitet vom compiler [public Foo(){}]; ein Konstruktor ohne Argumente.
Oft ich mag zu bieten Sie beide Ansätze. Erlauben Konstruktoren für diejenigen, die wünschen, Sie zu benutzen und dass das Feld-Initialisierungen für die Situationen, in denen Sie möchten, verwenden Sie eine vereinfachte oder default-Implementierung der Klasse /des Typs. Dies erhöht die Flexibilität Ihres Codes. Beachten Sie, dass jeder kann verwenden Sie das Feld "default" - Initialisierung, wenn Sie wählen ... sicher sein, zu erklären, es manuell ein, wenn Sie bieten mehr als eine Konstruktor - public Foo(){}
InformationsquelleAutor der Antwort Qubits