webentwicklung-frage-antwort-db.com.de

Methode kann statisch gemacht werden, aber sollte es?

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?

351
dlamblin

Statische Methoden versus Instanzmethoden
10.2.5 Statische und Instanzmitglieder der C # -Sprachenspezifikation erklärt den Unterschied. Im Allgemeinen können statische Methoden eine sehr kleine Leistungsverbesserung gegenüber Instanzmethoden bewirken, jedoch nur in etwas extremen Situationen (siehe diese Antwort für weitere Details dazu).

Regel CA1822 in FxCop oder Code Analysis lautet:

"Nach dem [Markieren von Mitgliedern als statisch] sendet der Compiler nicht virtuelle Aufrufsites an diese Mitglieder, wodurch eine Überprüfung zur Laufzeit für jeden Aufruf verhindert wird, die sicherstellt, dass der aktuelle Objektzeiger nicht null ist. Dies kann dazu führen ein messbarer Leistungsgewinn für leistungskritischen Code. In einigen Fällen stellt das Nichtzugreifen auf die aktuelle Objektinstanz ein Korrektheitsproblem dar. "

Gebrauchsklasse
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 vorhanden ist (beachten Sie, dass dies ein verschachteltes Beispiel ist zu Demonstrationszwecken).

235
Jeff Yates

Performance, Namespace-Verschmutzung usw. sind aus meiner Sicht 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 auf einen Typ bezieht, auf den Sie keinen Einfluss haben.

Manchmal gibt es Methoden, die logisch auf eine Instanz einwirken, aber zufällig keinen der Zustände der Instanz verwenden noch. Wenn Sie beispielsweise ein Dateisystem erstellen und das Konzept eines Verzeichnisses kennen, dieses jedoch noch nicht implementiert haben, können Sie eine Eigenschaft schreiben, die die Art des Dateisystemobjekts zurückgibt, und dies ist immer gerecht "file" - aber es ist logisch mit der Instanz verbunden und sollte daher eine Instanzmethode sein. Dies ist auch wichtig, wenn Sie die Methode virtualisieren möchten - Ihre bestimmte Implementierung benötigt möglicherweise keinen Status, aber möglicherweise abgeleitete Klassen. (Wenn Sie beispielsweise eine Sammlung fragen, ob sie schreibgeschützt ist oder nicht - Sie haben möglicherweise noch keine schreibgeschützte Form für diese Sammlung implementiert, aber dies ist eindeutig eine Eigenschaft der Sammlung selbst und nicht des Typs.)

252
Jon Skeet

Das Markieren einer Methode als static in einer Klasse macht deutlich, dass keine Instanzmember verwendet werden. Dies kann hilfreich sein, wenn Sie den Code durchsuchen.

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 verbunden ist.

54
Mark Cidade

Ich bin mir sicher, dass dies in Ihrem Fall nicht der Fall ist, aber ein "schlechter Geruch", den ich in einem Code gesehen habe, der unter der Verwendung einer Menge statischer Methoden zu leiden hatte.

Leider handelte es sich um statische Methoden, die einen bestimmten Anwendungszustand einnahmen. (Warum haben wir nur einen Benutzer pro Anwendung? Warum hat die Benutzerklasse nicht den Überblick über statische Variablen?) Es waren großartige Möglichkeiten, auf globale Variablen zuzugreifen. 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 die Domänenlogik ausklammern, die eigentlich nicht vom Status einer Instanz des Objekts abhängt. Sie können Ihren Code viel besser lesbar machen.

Stellen Sie nur sicher, dass Sie sie an der richtigen Stelle platzieren. Beeinflussen die statischen Methoden den internen Zustand anderer Objekte? Kann ein gutes Argument dafür sein, dass ihr Verhalten stattdessen zu einer dieser Klassen gehört? Wenn Sie Bedenken nicht richtig trennen, kann es später zu Kopfschmerzen kommen.

21
JasonTrue

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 sich diese Methode in dieser Klasse befindet und nicht beispielsweise in einer der Klassen, die in ihrer Signatur auftauchen ...

aber hier ist, was Resharper Documentaion sagt: http://confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static

9
pajics

Nur um @Jason Trues Antwort zu ergänzen, ist es wichtig zu wissen, dass das Setzen von 'static' auf eine Methode nicht garantiert, dass die Methode 'pure' ist. Es ist in Bezug auf die Klasse, in der es deklariert ist, zustandslos, greift aber möglicherweise auf andere 'statische' Objekte zu, 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 über sie nachdenken, ohne sich um den Umgebungszustand sorgen zu müssen.

8
Benjol

Für komplexe Logik innerhalb einer Klasse habe ich private statische Methoden gefunden, die beim Erstellen isolierter Logik nützlich sind, bei denen die Instanzeingaben in der Methodensignatur klar definiert sind und keine Instanzenebenwirkungen auftreten können. Alle Ausgänge müssen über Rückgabewert oder Out/Ref-Parameter erfolgen. Das Aufteilen komplexer Logik in nebenwirkungsfreie Codeblöcke kann die Lesbarkeit des Codes und das Vertrauen des Entwicklerteams in den Code verbessern.

Andererseits kann es zu einer Klasse kommen, die durch die Verbreitung von Gebrauchsmethoden verschmutzt ist. Wie üblich kann dies durch logische Benennung, Dokumentation und konsequente Anwendung von Team-Codierungskonventionen gelindert werden.

6
G-Wiz

Sie sollten in einem bestimmten Szenario das tun, was am besten lesbar und intuitiv ist.

Das Leistungsargument ist nicht gut, außer in den extremsten Situationen, da das einzige, was tatsächlich passiert, darin besteht, dass ein zusätzlicher Parameter (this) auf den Stack verschoben wird, zum Beispiel Methoden.

6
Eric Schoonover

ReSharper überprüft die Logik nicht. Es wird nur geprüft, ob die Methode Instanzmitglieder verwendet. Wenn die Methode privat ist und nur von (möglicherweise nur einer) Instanzmethode aufgerufen wird, ist dies ein Zeichen dafür, dass es sich um eine Instanzmethode handelt.

5
brgerner

Wenn Sie eine Methode statisch machen, können Sie die Methode von außerhalb der Klasse aufrufen, ohne zuerst 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.

3
Austin

Wenn die Funktionen für viele Seiten freigegeben sind, können Sie sie auch in eine Basisseitenklasse einfügen und dann alle asp.net-Seiten, die diese Funktionalität verwenden, von ihr erben lassen (und die Funktionen können auch noch statisch sein).

3
Mun

Es hilft, die Verschmutzung von Namespaces zu kontrollieren.

2
Josh

Nur mein Tipp: Wenn Sie einer Utility-Klasse alle gemeinsam genutzten statischen Methoden hinzufügen, können Sie diese hinzufügen

using static className; 

auf Ihre using-Anweisungen, die den Code schneller tippen und leichter lesbar machen. 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 die Aufgabe, wenn es chaotisch ist, und ich kann die Eigenschaften nur nach Namen referenzieren, da auf den statischen Namespace bereits verwiesen wurde.

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

0
Joseph Morgan