Ich habe eine abstrakte Klasse namens DatabaseRow
, die, nachdem sie abgeleitet und konstruiert wurde, hauptsächlich von einer Load(object id)
-Methode geladen wird.
Ich habe viel Code, der eine neue Instanz der Klasse erstellt, sie aus einer ID lädt und dann die Klasse zurückgibt. Ich möchte diesen Code in eine Codezeile vereinfachen (um ganz ordentlich zu sein, gibt es viele Klassen, die nur Listen mit Eigenschaften haben, die diese geladenen Instanzen zurückgeben).
Es gibt zwei Möglichkeiten, wie ich das machen kann, aber mir scheint es nicht "richtig" zu sein.
1. Ich könnte return this;
am Ende meiner Load
-Methode verwenden und return new Derived().Load(id);
2. Ich könnte eine generische Methode erstellen, um eine geladene Methode zurückzugeben.
%Vor%Ich habe einen anderen Code gesehen, der dieselbe Methode wie die Zahl 1 verwendet, aber ich habe noch nie einen erfahrenen Entwickler gesehen, der ihn empfohlen hat, noch bin ich auf Methoden im .NET-Framework gestoßen die dasselbe tun, also ist dies vielleicht nicht die beste Praxis?
Kennt jemand andere Lösungen, die besser als diese beiden sein könnten?
Lösung:
Nachdem ich SirVivers Antwort und Kommentar gelesen hatte, wurde mir klar, dass alle zurückgegebenen Eigenschaften sowieso zwischengespeichert werden müssen. Die Lösung war deutlich anders, aber ähnlich wie Option 2 (dass ich nicht erwarten würde, dass jemand auf diese Antwort kommt, da ich diesen Teil des Designs nicht erklärt habe)
Alle diese Instanzen werden aus einem Wert geladen, der aus einer anderen Spalte in der Datenbank abgerufen wird (Datenbankbeziehungen, wenn Sie möchten). Anstatt zu versuchen, die neue Instanz von diesem Wert zu laden, habe ich eine Methode zum Laden der Instanz aus dem Spaltennamen erstellt und den geladenen Wert in einem Dictionary zwischenspeichern. Dies funktioniert gut, da dies eine der Hauptfunktionen der Klasse DatabaseRow
ist.
Persönlich halte ich es für eine schlechte Methode, Methodenaufrufe zu verketten, die tatsächliche Nebeneffekte auf die Objektinstanz haben. Um ehrlich zu sein, denke ich, dass beide Beispiele ziemlich hässliche "Hacks" sind, deren einziger Zweck es ist, zwei Codezeilen zu speichern. Ich denke nicht, dass das Ergebnis auch lesbarer ist.
Wenn Sie möchten, dass ein Datensatz sofort geladen wird, würde ich wahrscheinlich lieber eine Konstruktordarstellung angeben, die die ID, von der Sie laden, liefert und das Objekt automatisch aufbaute, wenn ich darüber nachdenke, würde ich nicht Um ehrlich zu sein, stört man sich überhaupt nicht - mehr Informationen in einer einzigen Zeile zu stopfen macht nicht mehr lesbaren und wartbaren Code.
Nummer 1 gewinnt in einigen Kreisen an Popularität; es wird oft fließende Programmierung genannt, wenn es eine Schnittstelle gibt, die eine große Anzahl dieser Methoden definiert und lange Ketten zusammengebaut werden können. Der Schlüssel dafür ist, niemals eine Methode zu definieren, die manchmal this
zurückgibt, aber andere Male gibt null
zurück. Wenn this
immer zurückgegeben wird (es sei denn, es gibt eine Ausnahme), ist das ein perfekter Stil.
Ich persönlich bin nicht so begeistert von Lösungen wie Nummer 2, da man sagen könnte, dass sie das Prinzip der "eine Verantwortung" verletzen.
Option 1 ist nur akzeptabel, wenn es möglich ist, eine Zeile zu haben, ohne geladen zu werden. Dies liegt an dem Muster, das Ihnen dies ermöglicht:
%Vor%Ich persönlich würde die statische Methode bevorzugen. Aber ich vermute, dass es nur eine Frage der persönlichen Präferenz ist.
Wie ssg sagt, ist die andere Option (lasst es Option 3 nennen), den Konstruktor in Derived zu überlasten, was auch funktionieren würde. Allerdings kann es sehr verwirrend sein, viele Konstruktoren zu haben, da der aufrufende Code nichts enthält, was was beschreibt geht weiter.
Option 1:
%Vor%Option 2:
%Vor%Option 3:
%Vor%Option 1 sieht so aus, als ob Sie ein überflüssiges Objekt erstellt haben. Option 2 ist gut, weil sie so funktioniert, wie es aussieht. Option 3 lässt Verwirrung darüber, was es tut.
Obwohl ich persönlich Methoden mag, die this
zurückgeben, da es ihnen erlaubt, angekettet zu werden, denke ich, dass dies im .NET-Framework (bis zu Linq) verpönt war. Der Grund dafür ist folgender:
Methoden geben entweder ein Ergebnis zurück oder ändern den Status des Objekts. Die Rückgabe von this
ist ein bisschen von beidem: Ändern des Zustands des Objekts und Zurückgeben eines "Ergebnisses" - mit Ausnahme dieses Ergebnisses ist das modifizierte Originalobjekt. Dies entspricht nicht den Erwartungen des Benutzers.
Was ist mit:
%Vor%Und benutze es so:
%Vor%Tags und Links .net c# return-value