Resharper weist gerne auf mehrere Funktionen pro asp.net-Seite hin, die statisch gemacht werden könnten. Hilft es mir, wenn ich sie statisch mache? Soll ich sie statisch machen und in eine Utility-Klasse verschieben?
Resharper weist gerne auf mehrere Funktionen pro asp.net-Seite hin, die statisch gemacht werden könnten. Hilft es mir, wenn ich sie statisch mache? Soll ich sie statisch machen und in eine Utility-Klasse verschieben?
Antworten:
Statische Methoden versus
Instanzmethoden 10.2.5 Statische und Instanzmitglieder der C # -Sprachenspezifikation erklären den Unterschied. Im Allgemeinen können statische Methoden eine sehr geringe Leistungssteigerung gegenüber Instanzmethoden bieten, jedoch nur in etwas extremen Situationen (siehe diese Antwort für weitere Details dazu).
Regel CA1822 in FxCop oder Code Analysis besagt:
"Nach [Markieren von Mitgliedern als statisch] sendet der Compiler nicht virtuelle Aufrufseiten an diese Mitglieder, wodurch zur Laufzeit für jeden Aufruf eine Überprüfung verhindert wird, die sicherstellt, dass der aktuelle Objektzeiger nicht null ist. Dies kann zu einem messbaren Leistungsgewinn führen In einigen Fällen stellt der Fehler beim Zugriff auf die aktuelle Objektinstanz ein Korrektheitsproblem dar. "
Utility-Klasse
Sie sollten sie nicht in eine Utility-Klasse verschieben, es sei denn, dies ist in Ihrem Entwurf sinnvoll. Wenn sich die statische Methode auf einen bestimmten Typ bezieht, wie sich eine ToRadians(double degrees)
Methode auf eine Klasse bezieht, die Winkel darstellt, ist es sinnvoll, dass diese Methode als statisches Element dieses Typs existiert (beachten Sie, dass dies zu Demonstrationszwecken ein kompliziertes Beispiel ist).
Leistung, Verschmutzung des Namespace usw. sind meiner Ansicht nach zweitrangig. Fragen Sie sich, was logisch ist. Funktioniert die Methode logisch auf einer Instanz des Typs oder hängt sie mit dem Typ selbst zusammen? Wenn es das letztere ist, machen Sie es zu einer statischen Methode. Verschieben Sie es nur in eine Utility-Klasse, wenn es sich um einen Typ handelt, auf den Sie keinen Einfluss haben.
Manchmal gibt es Methoden , die logisch auf einer Instanz handeln , aber nicht passieren jede der Instanz des Staates zu verwenden , noch . Wenn Sie beispielsweise ein Dateisystem erstellen und das Konzept eines Verzeichnisses haben, es aber noch nicht implementiert haben, können Sie eine Eigenschaft schreiben, die die Art des Dateisystemobjekts zurückgibt, und es wäre immer gerecht "Datei" - aber es ist logisch mit der Instanz verbunden und sollte daher eine Instanzmethode sein. Dies ist auch wichtig, wenn Sie die Methode virtuell machen möchten - Ihre bestimmte Implementierung benötigt möglicherweise keinen Status, abgeleitete Klassen jedoch möglicherweise. (Wenn Sie beispielsweise eine Sammlung fragen, ob sie schreibgeschützt ist oder nicht, haben Sie möglicherweise noch keine schreibgeschützte Form dieser Sammlung implementiert, diese ist jedoch eindeutig eine Eigenschaft der Sammlung selbst und nicht des Typs.)
Markieren einer Methode als static
innerhalb einer Klasse markieren, wird deutlich, dass keine Instanzmitglieder verwendet werden. Dies kann hilfreich sein, wenn Sie den Code durchblättern.
Sie müssen es nicht unbedingt in eine andere Klasse verschieben, es sei denn, es soll von einer anderen Klasse geteilt werden, die konzeptionell genauso eng miteinander verbunden ist.
Ich bin mir sicher, dass dies in Ihrem Fall nicht der Fall ist, aber ein "schlechter Geruch", den ich in einem Code gesehen habe, unter dem ich leiden musste, weil ich eine Menge statischer Methoden verwendet habe.
Leider handelte es sich um statische Methoden, die einen bestimmten Anwendungsstatus annahmen. (Warum sicher, wir haben nur einen Benutzer pro Anwendung! Warum sollte die Benutzerklasse dies nicht in statischen Variablen verfolgen?) Es handelte sich um verherrlichte Methoden für den Zugriff auf globale Variablen. Sie hatten auch statische Konstruktoren (!), Was fast immer eine schlechte Idee ist. (Ich weiß, dass es ein paar vernünftige Ausnahmen gibt).
Statische Methoden sind jedoch sehr nützlich, wenn sie Domänenlogik herausrechnen, die nicht vom Status einer Instanz des Objekts abhängt. Sie können Ihren Code viel lesbarer machen.
Stellen Sie nur sicher, dass Sie sie an der richtigen Stelle platzieren. Manipulieren die statischen Methoden auf intrusive Weise den internen Zustand anderer Objekte? Kann man gut behaupten, dass ihr Verhalten stattdessen zu einer dieser Klassen gehört? Wenn Sie Bedenken nicht richtig trennen, kann es später zu Kopfschmerzen kommen.
Das ist interessant zu lesen:
http://thecuttingledge.com/?p=57
ReSharper schlägt nicht vor, dass Sie Ihre Methode statisch machen. Sie sollten sich fragen, warum diese Methode in dieser Klasse enthalten ist, im Gegensatz zu beispielsweise einer der Klassen, die in ihrer Signatur angezeigt werden ...
Aber hier ist, was resharper documentaion sagt: http://confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static
Nur um die Antwort von @Jason True zu ergänzen , ist es wichtig zu wissen , dass das bloße Setzen von 'statisch' auf eine Methode nicht garantiert, dass die Methode 'rein' ist. Es wird in Bezug auf die Klasse, in der es deklariert ist, zustandslos sein, aber es kann durchaus auf andere 'statische' Objekte zugreifen, die einen Status haben (Anwendungskonfiguration usw.). Dies ist möglicherweise nicht immer eine schlechte Sache, aber einer der Gründe dafür Ich persönlich bevorzuge statische Methoden, wenn ich kann: Wenn sie rein sind, können Sie sie isoliert testen und begründen, ohne sich um den Umgebungszustand sorgen zu müssen.
Sie sollten das tun, was in einem bestimmten Szenario am besten lesbar und intuitiv ist.
Das Leistungsargument ist nur in den extremsten Situationen gut, da das einzige, was tatsächlich passiert, ist, dass ein zusätzlicher Parameter ( this
) zum Beispiel Methoden auf den Stapel geschoben wird.
Für komplexe Logik innerhalb einer Klasse habe ich private statische Methoden gefunden, die beim Erstellen einer isolierten Logik nützlich sind, bei der die Instanzeingaben in der Methodensignatur klar definiert sind und keine Instanznebenwirkungen auftreten können. Alle Ausgänge müssen über Rückgabewert oder Out / Ref-Parameter erfolgen. Aufteilung der komplexen Logik in nebenwirkungsfreie Codeblöcke kann die Lesbarkeit des Codes und das Vertrauen des Entwicklungsteams in ihn verbessern.
Andererseits kann es zu einer Klasse kommen, die durch eine Vielzahl von Gebrauchsmethoden verschmutzt ist. Wie üblich können logische Benennung, Dokumentation und konsistente Anwendung von Teamcodierungskonventionen dies erleichtern.
Wenn Sie eine Methode statisch machen, können Sie die Methode von außerhalb der Klasse aufrufen, ohne zuvor eine Instanz dieser Klasse zu erstellen. Dies ist hilfreich, wenn Sie mit Objekten oder Add-Ons von Drittanbietern arbeiten. Stellen Sie sich vor, Sie müssten zuerst ein Konsolenobjekt "con" erstellen, bevor Sie con.Writeline () aufrufen.
Es hilft, die Verschmutzung durch Namespaces zu kontrollieren.
Class.a_core_function( .. )
vsa_core_function( .. )
Nur meine Antwort: Wenn Sie einer Dienstprogrammklasse alle gemeinsam genutzten statischen Methoden hinzufügen, können Sie sie hinzufügen
using static className;
zu Ihren using-Anweisungen, wodurch der Code schneller eingegeben und leichter gelesen werden kann. Zum Beispiel habe ich eine große Anzahl von sogenannten "globalen Variablen" in einem Code, den ich geerbt habe. Anstatt globale Variablen in einer Klasse zu erstellen, die eine Instanzklasse war, habe ich sie alle als statische Eigenschaften einer globalen Klasse festgelegt. Es erledigt den Job, wenn auch unordentlich, und ich kann die Eigenschaften nur nach Namen referenzieren, da auf den statischen Namespace bereits verwiesen wird.
Ich habe keine Ahnung, ob dies eine gute Praxis ist oder nicht. Ich muss so viel über C # 4/5 und so viel Legacy-Code lernen, dass ich nur versuche, mich von den Roselyn-Tipps leiten zu lassen.
Joey
Ich hoffe, Sie haben den Unterschied zwischen statischen und Instanzmethoden bereits verstanden. Es kann auch eine lange und eine kurze Antwort geben. Lange Antworten geben bereits andere.
Meine kurze Antwort: Ja, Sie können sie in statische Methoden konvertieren, wenn Resharper dies vorschlägt. Das schadet nicht. Indem Sie die Methode statisch machen, schützen Sie die Methode tatsächlich so, dass Sie unnötigerweise keine Instanzmitglieder in diese Methode verschieben. Auf diese Weise können Sie ein OOP-Prinzip erreichen: " Minimieren Sie die Zugänglichkeit von Klassen und Mitgliedern ".
Wenn ReSharper vorschlägt, dass eine Instanzmethode in eine statische Methode konvertiert werden kann, heißt es tatsächlich: "Warum befindet sich diese Methode in dieser Klasse, da sie keinen ihrer Zustände verwendet?" Es gibt Ihnen also Denkanstöße. Dann können Sie erkennen, dass diese Methode in eine statische Dienstprogrammklasse verschoben werden muss oder nicht. Nach den SOLID-Prinzipien sollte eine Klasse nur eine Kernverantwortung haben. Auf diese Weise können Sie Ihre Klassen besser bereinigen. Manchmal benötigen Sie sogar in Ihrer Instanzklasse einige Hilfsmethoden. In diesem Fall können Sie sie in einem # region-Helfer aufbewahren.