Ich habe mit einem Entwickler gearbeitet, der viele Jahre in C # Erfahrung hatte. Ich habe keine Möglichkeit mehr, ihn zu kontaktieren, und ich erinnere mich, dass er gesagt hat, dass es keine gute Idee ist, Code in einen Standardparameter ohne Konstruktor aufzunehmen, aber ich kann mich nicht an den Grund erinnern.
Ist es eine gute Übung oder schlechte Übung, Code in den Standardkonstruktor in C # oder in eine andere Sprache zu integrieren?
Das hängt von der Situation ab, manchmal ist es notwendig, manchmal kann es benutzt werden, manchmal sollte es nicht da sein.
Wichtig ist, dass jeder Konstruktor das Objekt in einem ordnungsgemäß initialisierten Zustand belassen soll. Wenn ein Objekt immer etwas Code zum Initialisieren benötigt, aber keine spezielle Eingabe, wäre ein parameterloser Konstruktor dafür ein guter Platz.
Was mir in den Sinn kommt, ist Punkt 17 von Effective Java (von Joshua Bloch):
Punkt 17: Design und Dokument für die Vererbung oder verbieten es
Er erklärt, dass ein Konstruktor keine überschreibbaren Methoden aufrufen sollte:
%Vor%Was passiert, ist, dass Sie den Konstruktor der Oberklasse aufrufen (wenn Sie eine Instanz der Unterklasse erstellen) und Sie unerwartetes Verhalten erhalten.
Wenn Ihr Konstruktor andere Methoden in der Klasse aufruft, müssen Sie dies in Ihrer API dokumentieren, damit Entwickler, wenn sie eine Unterklasse bilden, wissen, was zu erwarten ist.
Andernfalls kann der Code in Ihrem Konstruktor nicht beschädigt werden.
Da Sie C # mit dem .NET-Framework verwenden. Lassen Sie mich Ihnen den vollständigen "Constructor Design" -Artikel von MSDN geben:
Meiner Meinung nach sollten Sie nur Initialisierungscode in Ihren Konstruktor einfügen.
Wenn Sie ein Objekt mit einem BinaryFormatter deserialisieren, wird der Standardkonstruktor nicht ausgeführt, wenn das Objekt erstellt wird. Der BinaryFormatter verwendet einen Trick, um .NET eine initialisierte Instanz zu geben, in der keine Standardkonstruktoren ausgeführt werden.
Dies sollte kein Problem darstellen, da der BinaryFormatter alle privaten Mitglieder selbst ausfüllt. Die einzige Situation, die ich mir gefährlich vorstellen kann, ist, wenn Sie den Standardkonstruktor verwenden, um das Objekt irgendwo in einer anderen statischen Klasse oder etwas in dieser Richtung zu "registrieren". In diesem Fall haben Sie eine ganze Reihe neuer Probleme. p>
Faustregel
Mach es so einfach wie möglich.
Der ganze Sinn von guten Codierungsstandards liegt in Wartbarkeit und Debug-Fähigkeit. Wir alle sind auf Code gestoßen, der Spaghetti ist. Dies ist nur, damit andere Ihre API besser verstehen. Selbst mit gutem Javadoc erwarten die meisten nicht, dass der Konstruktor den Anwendungsstatus ändert.
Wenn zum Beispiel Ihr Objekt eine Datenbankmanipulation durchführt, haben Sie einen verdammt guten Grund.
Counter-Beispiel
Sie müssen immer noch tun, was das Beste ist. Wenn Sie sich entscheiden, einen Lazy-Loaded Singleton zu haben, der einen Cache oder eine Verbindung lädt oder was Sie haben, ist der ganze Punkt, dass er automatisch etwas lädt, wenn Sie es instanziieren.
Ich weiß, dass wir die Initialisierung für alle Parameter im Standardkonstruktor aufrufen. Es gibt Zeiten, in denen wir die Daten außerhalb nur der Deklaration "leeren" müssen, also tun wir es in einer separaten Methode und rufen es im niedrigsten Konstruktor für jedes Objekt auf.
Es ist eine Frage des Geschmacks. Ich finde diese vom Benutzer kokos definierten Regeln sehr hilfreich:
seine Regeln:
- Initialisieren Sie nicht mit den Standardwerten in der Deklaration (null, false, 0, 0.0 ...).
- Ziehen Sie die Initialisierung in der Deklaration vor, wenn Sie keinen Konstruktorparameter haben, der den Wert des Feldes ändert.
- Wenn sich der Wert des Feldes wegen eines Konstruktor-Parameters ändert, setzen Sie die Initialisierung in die Konstruktoren.
- Sei konsistent in deiner Praxis. (die wichtigste Regel)
siehe: Initialisieren Sie Klassenfelder im Konstruktor oder unter Erklärung?
Uinitialisierte Klassenfelder sollten normalerweise im Standardkonstruktor enden. Wenn Sie Klassenfelder in derselben Zeile wie die Deklarationen initialisieren, werden diese Anweisungen nicht ausgeführt, wenn Sie ein solches Objekt deserialisieren. Außerdem ist es eine gute Übung, alle Initialisierungen im Standard-ctor zu sammeln.