webentwicklung-frage-antwort-db.com.de

Wann werden statische Klassen in C # verwendet?

Hier ist was MSDN muss unter sagen, wann statische Klassen zu verwenden sind :

static class CompanyInfo
{
    public static string GetCompanyName() { return "CompanyName"; }
    public static string GetCompanyAddress() { return "CompanyAddress"; }
    //...
}

Verwenden Sie eine statische Klasse als Organisationseinheit für Methoden, die nicht bestimmten Objekten zugeordnet sind. Außerdem kann eine statische Klasse Ihre Implementierung vereinfachen und beschleunigen, da Sie kein Objekt erstellen müssen, um seine Methoden aufzurufen. Es ist hilfreich, die Methoden in der Klasse auf sinnvolle Weise zu organisieren, z. B. die Methoden der Math-Klasse im System-Namespace.

Für mich scheint dieses Beispiel nicht viele mögliche Verwendungsszenarien für statische Klassen abzudecken. In der Vergangenheit habe ich statische Klassen für zustandslose Suites verwandter Funktionen verwendet, aber das war es auch schon. Unter welchen Umständen sollte (und sollte nicht) eine Klasse als statisch deklariert werden?

591
pbh101

Ich habe meine Gedanken zu statischen Klassen in einer früheren Stack Overflow-Antwort geschrieben: Klasse mit einer einzelnen Methode - bester Ansatz?

Früher liebte ich Utility-Klassen, die mit statischen Methoden gefüllt waren. Sie haben eine großartige Konsolidierung von Hilfsmethoden vorgenommen, die andernfalls Redundanz und Wartungsaufwand verursachen würden. Sie sind sehr einfach zu bedienen, keine Instantiierung, keine Entsorgung, nur Feuer und Vergessen. Ich denke, dies war mein erster unbeabsichtigter Versuch, eine serviceorientierte Architektur zu schaffen - viele zustandslose Services, die nur ihren Job gemacht haben und sonst nichts. Während ein System wächst, kommen jedoch Drachen.

Polymorphismus

Nehmen wir an, wir haben die Methode UtilityClass.SomeMethod, die glücklich mitschwirrt. Plötzlich müssen wir die Funktionalität etwas ändern. Der größte Teil der Funktionalität ist derselbe, aber wir müssen trotzdem einige Teile ändern. Wäre es keine statische Methode gewesen, könnten wir eine Derivate-Klasse erstellen und den Methodeninhalt nach Bedarf ändern. Da es eine statische Methode ist, können wir nicht. Klar, wenn wir nur Funktionalität vor oder nach der alten Methode hinzufügen müssen, können wir eine neue Klasse erstellen und die alte in ihr aufrufen - aber das ist nur eklatant.

Probleme mit der Benutzeroberfläche

Statische Methoden können aus logischen Gründen nicht über Schnittstellen definiert werden. Und da wir statische Methoden nicht überschreiben können, sind statische Klassen nutzlos, wenn wir sie über ihre Schnittstelle weitergeben müssen. Dies macht es uns unmöglich, statische Klassen als Teil eines Strategiemusters zu verwenden. Wir können einige Probleme beheben, indem wir Delegierte anstelle von Schnittstellen übergeben .

Testen

Dies geht im Wesentlichen mit den oben erwähnten Problemen der Benutzeroberfläche einher. Da wir nur sehr eingeschränkte Möglichkeiten haben, Implementierungen auszutauschen, können wir auch den Produktionscode nicht durch Testcode ersetzen. Wir können sie wieder einpacken, müssen jedoch große Teile unseres Codes ändern, um Wrapper anstelle der eigentlichen Objekte akzeptieren zu können.

Fördert Blobs

Da statische Methoden in der Regel als Dienstprogrammmethoden verwendet werden und Dienstprogrammmethoden in der Regel unterschiedliche Zwecke haben, erhalten wir schnell eine große Klasse mit nicht kohärenter Funktionalität - im Idealfall sollte jede Klasse einen einzigen Zweck innerhalb des Systems haben. Ich hätte viel lieber eine fünffache Klasse, solange ihre Ziele klar definiert sind.

Parameter Creep

Zunächst könnte diese kleine nette und unschuldige statische Methode einen einzigen Parameter annehmen. Mit zunehmender Funktionalität werden einige neue Parameter hinzugefügt. Bald werden weitere Parameter hinzugefügt, die optional sind, sodass wir Überladungen der Methode erstellen (oder einfach Standardwerte in Sprachen hinzufügen, die diese unterstützen). In Kürze haben wir eine Methode, die 10 Parameter akzeptiert. Nur die ersten drei sind wirklich erforderlich, Parameter 4-7 sind optional. Wenn jedoch Parameter 6 angegeben wird, müssen auch 7-9 ausgefüllt werden. Hätten wir eine Klasse mit dem einzigen Zweck erstellt, das zu tun, was diese statische Methode getan hat, könnten wir dies lösen, indem wir die erforderlichen Parameter in das Feld eingeben Der Benutzer kann optionale Werte über Eigenschaften oder Methoden festlegen, um mehrere voneinander abhängige Werte gleichzeitig festzulegen. Wenn eine Methode auf diese Komplexität angewachsen ist, muss sie höchstwahrscheinlich ohnehin in einer eigenen Klasse sein.

Fordert die Konsumenten auf, ohne Grund eine Instanz von Klassen zu erstellen

Eines der häufigsten Argumente ist: Warum fordern Sie, dass Verbraucher unserer Klasse eine Instanz zum Aufrufen dieser einzelnen Methode erstellen, ohne die Instanz danach zu verwenden? Das Erstellen einer Instanz einer Klasse ist in den meisten Sprachen eine sehr, sehr kostengünstige Operation, daher spielt Geschwindigkeit keine Rolle. Das Hinzufügen einer zusätzlichen Codezeile für den Verbraucher ist mit geringen Kosten verbunden, um den Grundstein für eine in Zukunft viel wartbarere Lösung zu legen. Wenn Sie keine Instanzen erstellen möchten, erstellen Sie einfach einen Singleton-Wrapper für Ihre Klasse, der eine einfache Wiederverwendung ermöglicht. Dies setzt jedoch voraus, dass Ihre Klasse statusfrei ist. Wenn es nicht zustandslos ist, können Sie dennoch statische Wrapper-Methoden erstellen, die alles verarbeiten und Ihnen auf lange Sicht dennoch alle Vorteile bieten. Schließlich können Sie auch eine Klasse erstellen, die die Instanziierung als Singleton verbirgt: MyWrapper.Instance ist eine Eigenschaft, die nur new MyClass(); zurückgibt.

Nur ein Sith handelt in absoluten Zahlen

Natürlich gibt es Ausnahmen von meiner Abneigung gegen statische Methoden. Echte Utility-Klassen, die kein Aufblähungsrisiko darstellen, eignen sich hervorragend für statische Methoden - am Beispiel von System.Convert. Wenn es sich bei Ihrem Projekt um ein einmaliges Projekt handelt, für das keine zukünftigen Wartungsarbeiten erforderlich sind, spielt die Gesamtarchitektur keine große Rolle - statisch oder nicht statisch, spielt jedoch keine Rolle - die Entwicklungsgeschwindigkeit.

Standards, Standards, Standards!

Die Verwendung von Instanzmethoden hindert Sie nicht daran, auch statische Methoden zu verwenden und umgekehrt. Solange die Unterscheidung begründet und standardisiert ist. Es gibt nichts Schlimmeres, als einen Blick auf eine Business-Schicht zu werfen, die sich aus verschiedenen Implementierungsmethoden zusammensetzt.

711

Bei der Entscheidung, ob eine Klasse statisch oder nicht statisch sein soll, müssen Sie sich ansehen, welche Informationen Sie darstellen möchten. Dies beinhaltet einen eher 'bottom-up' Programmierstil, bei dem Sie sich auf die Daten konzentrieren, die Sie zuerst darstellen. Ist die Klasse, die Sie schreiben, ein reales Objekt wie ein Stein oder ein Stuhl? Diese Objekte sind physisch und weisen physische Attribute wie Farbe und Gewicht auf. Dies weist darauf hin, dass Sie möglicherweise mehrere Objekte mit unterschiedlichen Eigenschaften instanziieren möchten. Ich möchte vielleicht gleichzeitig einen schwarzen UND einen roten Stuhl. Wenn Sie jemals zwei Konfigurationen zur gleichen Zeit benötigen, wissen Sie sofort, dass Sie sie als Objekt instanziieren möchten, damit jedes Objekt einzigartig sein und zur gleichen Zeit existieren kann.

Andererseits verleihen statische Funktionen eher Aktionen, die nicht zu einem realen Objekt oder einem Objekt gehören, das Sie einfach darstellen können. Denken Sie daran, dass die Vorgänger von C # C++ und C sind, in denen Sie nur globale Funktionen definieren können, die in einer Klasse nicht vorhanden sind. Dies verleiht der 'top-down' Programmierung mehr. Statische Methoden können in solchen Fällen verwendet werden, in denen es nicht sinnvoll ist, dass ein Objekt die Aufgabe ausführt. Indem Sie die Verwendung von Klassen erzwingen, wird es einfacher, verwandte Funktionen zu gruppieren, wodurch Sie besser wartbaren Code erstellen können.

Die meisten Klassen können entweder statisch oder nicht statisch dargestellt werden. Wenn Sie jedoch Zweifel haben, kehren Sie einfach zu Ihren OOP Wurzeln zurück und überlegen Sie, was Sie darstellen. Handelt es sich um ein Objekt, das eine Aktion ausführt (ein Auto, das beschleunigen, verlangsamen, wenden kann) oder um etwas Abstrakteres (z. B. Anzeigen der Ausgabe).

Treten Sie in Kontakt mit Ihrem inneren OOP und Sie können nie falsch liegen!

144
Despertar

In C # 3.0 sind Erweiterungsmethoden möglicherweise nur in statischen Klassen der obersten Ebene vorhanden.

35
Mark Cidade

Wenn Sie Codeanalyse-Tools verwenden (z. B. FxCop ), wird empfohlen, dass Sie eine Methode static markieren, wenn diese Methode nicht auf Instanzdaten zugreift. Das Grundprinzip ist, dass es einen Leistungsgewinn gibt. MSDN: CA1822 - Mitglieder als statisch markieren .

Es ist eher eine Richtlinie als eine Regel, wirklich ...

22
user25306

Ich benutze eher statische Klassen für Fabriken. Dies ist beispielsweise die Protokollierungsklasse in einem meiner Projekte:

public static class Log
{
   private static readonly ILoggerFactory _loggerFactory =
      IoC.Resolve<ILoggerFactory>();

   public static ILogger For<T>(T instance)
   {
      return For(typeof(T));
   }

   public static ILogger For(Type type)
   {
      return _loggerFactory.GetLoggerFor(type);
   }
}

Möglicherweise haben Sie sogar bemerkt, dass die IoC mit einem statischen Accessor aufgerufen wird. Die meisten Wenn Sie statische Methoden für eine Klasse aufrufen können, ist dies alles, was Sie tun können, damit die Klasse aus Gründen der Übersichtlichkeit als statisch gekennzeichnet wird.

12
Rob

Statische Klassen sind sehr nützlich und haben einen Platz, zum Beispiel Bibliotheken.

Das beste Beispiel, das ich zur Verfügung stellen kann, ist die .Net Math-Klasse, eine statische Klasse für den Systemnamespace, die eine Bibliothek mit mathematischen Funktionen enthält.

Es ist wie bei allem anderen, das richtige Werkzeug für den Job zu verwenden, und wenn nicht, kann alles missbraucht werden.

Statische Klassen als falsch abzulehnen, sie nicht zu verwenden oder zu sagen, "es kann nur eine geben" oder keine, ist genauso falsch wie über die Verwendung der Klassen.

C # .Net enthält eine Reihe von statischen Klassen, die genau wie die Math-Klasse verwendet werden.

Bei richtiger Implementierung sind sie also äußerst nützlich.

Wir haben eine statische TimeZone-Klasse, die eine Reihe von geschäftsbezogenen Zeitzonenfunktionen enthält. Es ist nicht erforderlich, mehrere Instanzen der Klasse zu erstellen, ähnlich der Math-Klasse. Sie enthält eine Reihe von global zugänglichen TimeZone-realisierten Funktionen (Methoden) in einer statischen Klasse .

10
Don

Ich habe damit begonnen, statische Klassen zu verwenden, wenn ich Funktionen anstelle von Klassen als Wiederverwendungseinheit verwenden möchte. Bisher ging es mir nur um das Böse der statischen Klassen. Durch das Lernen von F # habe ich sie jedoch in einem neuen Licht gesehen.

Was meine ich damit? Sagen wir mal, wenn ich einen super DRY Code ausarbeite, habe ich ein paar Ein-Methoden-Klassen. Ich kann diese Methoden einfach in eine statische Klasse ziehen und sie dann mithilfe eines Delegaten in Abhängigkeiten einfügen. Das spielt sich auch gut mit meinem Dependency Injection (DI) Container der Wahl Autofac.

Natürlich ist eine direkte Abhängigkeit von einer statischen Methode immer noch normalerweise böse (es gibt einige nicht-böse Verwendungen).

10
bentayloruk

Ich benutze statische Klassen als Mittel, um "zusätzliche Funktionalität" zu definieren, die ein Objekt eines bestimmten Typs unter einem bestimmten Kontext verwenden könnte. Normalerweise erweisen sie sich als Utility-Klassen.

Abgesehen davon denke ich, dass "Verwenden Sie eine statische Klasse als Organisationseinheit für Methoden, die nicht mit bestimmten Objekten verknüpft sind." Beschreiben Sie recht gut ihren Verwendungszweck.

9
Trap

Dies ist eine weitere alte, aber sehr heiße Frage, seit OOP aufgetreten ist. Es gibt natürlich viele Gründe, eine statische Klasse zu verwenden (oder nicht), und die meisten davon wurden in der Vielzahl der Antworten behandelt.

Ich addiere nur meine 2 Cent dazu und sage, dass ich eine Klasse statisch mache, wenn diese Klasse etwas ist, das im System einzigartig wäre und es wirklich keinen Sinn macht, Instanzen davon im Programm zu haben. Ich reserviere diese Verwendung jedoch für große Klassen. Ich erkläre niemals so kleine Klassen wie im MSDN-Beispiel als "statisch" und sicherlich nicht Klassen, die Mitglieder anderer Klassen sein werden.

Ich möchte auch erwähnen, dass static Methoden und static Klassen zwei verschiedene Dinge sind, die zu berücksichtigen sind. Die Hauptnachteile, die in der akzeptierten Antwort erwähnt werden, sind für statisches Methoden. static classes bietet die gleiche Flexibilität wie normale Klassen (in Bezug auf Eigenschaften und Parameter), und alle in ihnen verwendeten Methoden sollten für den Zweck der Existenz der Klasse relevant sein.

Ein gutes Beispiel für einen Kandidaten für eine statische Klasse ist meiner Meinung nach eine "FileProcessing" -Klasse, die alle Methoden und Eigenschaften enthält, die für die verschiedenen Objekte des Programms relevant sind, um komplexe FileProcessing-Vorgänge auszuführen. Es hat kaum eine Bedeutung, mehr als eine Instanz dieser Klasse zu haben, und wenn Sie statisch sind, steht sie allen in Ihrem Programm zur Verfügung.

7
ThunderGr

Ich verwende nur statische Klassen für Hilfsmethoden, aber mit dem Aufkommen von C # 3.0 würde ich lieber Erweiterungsmethoden für diese verwenden.

Ich verwende selten statische Klassenmethoden aus den gleichen Gründen, aus denen ich selten das singleton "Entwurfsmuster" verwende.

2
jonnii

Basierend auf MSDN :

  1. Sie können die Instanz nicht für statische Klassen erstellen
  2. Wenn die Klasse als statisch deklariert ist, sollte die Mitgliedsvariable für diese Klasse statisch sein
  3. Versiegelt [Kann nicht vererbt werden]
  4. Kann keinen Instanzkonstruktor enthalten
  5. Speicherverwaltung

Beispiel: Mathematische Berechnungen (mathematische Werte) ändern sich nicht [STANDARDBERECHNUNG FÜR DEFINIERTE WERTE]

1
Vicky