674 Stimmen

Wann man statische Klassen in C# verwenden sollte

Das ist es, was MSDN hat zu sagen unter Wann sollten statische Klassen verwendet werden? :

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

Verwenden Sie eine statische Klasse als eine Einheit von Organisationseinheit für Methoden, die die nicht mit bestimmten Objekten verbunden sind. Außerdem kann eine statische Klasse Ihre Implementierung einfacher und schneller machen weil Sie kein Objekt erstellen müssen Objekt erstellen müssen, um seine Methoden aufzurufen. Es ist nützlich, die Methoden innerhalb der Klasse sinnvoll zu organisieren, wie zum Beispiel die Methoden der Klasse Math im Namespace System.

Mir scheint, dass dieses Beispiel nicht sehr viele mögliche Einsatzszenarien für statische Klassen abdeckt. In der Vergangenheit habe ich statische Klassen für stateless Suites verwandter Funktionen verwendet, aber das war's auch schon. Unter welchen Umständen sollte eine Klasse also als statisch deklariert werden (und unter welchen nicht)?

782voto

Mark S. Rasmussen Punkte 33348

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

Früher liebte ich Utility-Klassen, die mit statischen Methoden gefüllt waren. Sie ermöglichten eine großartige Konsolidierung von Hilfsmethoden, die andernfalls herumliegen und Redundanz und Wartungsaufwand verursachen würden. Sie sind sehr einfach zu verwenden, keine Instanziierung, keine Entsorgung, einfach abfeuern und vergessen. Ich schätze, das war mein erster unwissentlicher Versuch, eine serviceorientierte Architektur zu schaffen - viele zustandslose Dienste, die einfach nur ihre Aufgabe erfüllen und sonst nichts. Wenn ein System jedoch wächst, werden Drachen kommen.

Polymorphismus

Angenommen, wir haben die Methode UtilityClass.SomeMethod, die fröhlich vor sich hin brummt. Plötzlich müssen wir die Funktionalität leicht ändern. Der größte Teil der Funktionalität ist derselbe, aber wir müssen trotzdem ein paar Teile ändern. Wenn es sich nicht um eine statische Methode handeln würde, könnten wir eine abgeleitete Klasse erstellen und den Inhalt der Methode nach Bedarf ändern. Da es sich um eine statische Methode handelt, können wir das nicht. Natürlich können wir eine neue Klasse erstellen und darin die alte Methode aufrufen, wenn wir nur eine Funktion vor oder nach der alten Methode hinzufügen wollen - aber das ist einfach nur grob.

Probleme mit der Schnittstelle

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 unmöglich, statische Klassen als Teil eines Strategiemusters zu verwenden. Wir könnten einige Probleme beheben, indem wir Übergabe von Delegierten anstelle von Schnittstellen .

Prüfung

Dies geht im Grunde Hand in Hand mit den oben erwähnten Schnittstellenproblemen. Da unsere Möglichkeiten, Implementierungen auszutauschen, sehr begrenzt sind, werden wir auch Probleme haben, den Produktionscode durch Testcode zu ersetzen. Auch hier können wir sie verpacken, aber das erfordert, dass wir große Teile unseres Codes ändern, nur um Wrapper anstelle der eigentlichen Objekte akzeptieren zu können.

Fosters Kleckse

Da statische Methoden in der Regel als Utility-Methoden verwendet werden und Utility-Methoden in der Regel verschiedene Zwecke haben, werden wir schnell mit einer großen Klasse enden, die mit nicht kohärenter Funktionalität gefüllt ist - idealerweise sollte jede Klasse einen einzigen Zweck innerhalb des Systems haben. Mir wäre eine fünffache Anzahl von Klassen viel lieber, solange ihre Zwecke gut definiert sind.

Kriechende Parameter

Zunächst einmal könnte diese kleine, niedliche und unschuldige statische Methode einen einzigen Parameter annehmen. Wenn die Funktionalität wächst, werden ein paar neue Parameter hinzugefügt. Bald kommen weitere Parameter hinzu, die optional sind, so dass wir Überladungen der Methode erstellen (oder einfach Standardwerte hinzufügen, in Sprachen, die dies unterstützen). Schon bald haben wir eine Methode, die 10 Parameter benötigt. Nur die ersten drei sind wirklich erforderlich, die Parameter 4-7 sind optional. Aber wenn Parameter 6 angegeben wird, müssen auch die Parameter 7-9 ausgefüllt werden... Hätten wir eine Klasse mit dem einzigen Zweck erstellt, das zu tun, was diese statische Methode tat, könnten wir dieses Problem lösen, indem wir die erforderlichen Parameter in den Konstruktor aufnehmen und dem Benutzer erlauben, optionale Werte über Eigenschaften oder Methoden zu setzen, um mehrere voneinander abhängige Werte gleichzeitig zu setzen. Wenn eine Methode eine derartige Komplexität erreicht hat, muss sie höchstwahrscheinlich ohnehin in einer eigenen Klasse untergebracht werden.

Aufforderung an die Verbraucher, ohne Grund eine Instanz von Klassen zu erstellen

Eines der häufigsten Argumente lautet: Warum verlangen wir, dass die Verbraucher unserer Klasse eine Instanz erzeugen, um diese eine Methode aufzurufen, während sie danach keine Verwendung mehr für diese Instanz haben? Die Erzeugung einer Instanz einer Klasse ist in den meisten Sprachen ein sehr billiger Vorgang, so dass die Geschwindigkeit keine Rolle spielt. Die Hinzufügung einer zusätzlichen Codezeile für den Verbraucher ist ein geringer Preis für die Schaffung der Grundlage für eine viel besser wartbare Lösung in der Zukunft. Und schließlich, wenn Sie die Erstellung von Instanzen vermeiden wollen, erstellen Sie einfach einen Singleton-Wrapper Ihrer Klasse, der eine einfache Wiederverwendung ermöglicht - allerdings setzt dies voraus, dass Ihre Klasse zustandslos ist. Wenn sie nicht zustandslos ist, können Sie immer noch statische Wrapper-Methoden erstellen, die alles handhaben und Ihnen auf lange Sicht alle Vorteile bieten. Schließlich können Sie auch eine Klasse erstellen, die die Instanziierung verbirgt, als ob sie ein Singleton wäre: MyWrapper.Instance ist eine Eigenschaft, die einfach zurückgibt new MyClass();

Nur ein Sith handelt in absoluten Zahlen

Natürlich gibt es Ausnahmen von meiner Abneigung gegenüber statischen Methoden. Echte Utility-Klassen, die kein Risiko der Aufblähung darstellen, sind hervorragende Fälle für statische Methoden - System.Convert als Beispiel. Wenn es sich bei Ihrem Projekt um ein einmaliges Projekt handelt, das nicht gewartet werden muss, ist die Gesamtarchitektur wirklich nicht sehr wichtig - statisch oder nicht statisch spielt keine Rolle - die Entwicklungsgeschwindigkeit hingegen schon.

Normen, Normen, Normen!

Die Verwendung von Instanzmethoden hindert Sie nicht daran, auch statische Methoden zu verwenden, und umgekehrt. Solange es eine Begründung für die Unterscheidung gibt und diese standardisiert ist. Es gibt nichts Schlimmeres, als eine Geschäftsschicht zu sehen, in der es von verschiedenen Implementierungsmethoden wimmelt.

169voto

Despertar Punkte 20373

Bei der Entscheidung, ob eine Klasse statisch oder nicht statisch sein soll, müssen Sie sich überlegen, welche Informationen Sie darstellen wollen. Dies führt zu einem mehr ' Bottom-up Programmierstil, bei dem Sie sich zunächst auf die Daten konzentrieren, die Sie darstellen. Ist die Klasse, die Sie schreiben, ein reales Objekt wie ein Stein oder ein Stuhl? Diese Dinge sind physisch und haben physische Attribute wie Farbe und Gewicht, was Ihnen sagt, dass Sie vielleicht mehrere Objekte mit unterschiedlichen Eigenschaften instanziieren wollen. Ich möchte vielleicht einen schwarzen Stuhl UND einen roten Stuhl gleichzeitig. Wenn Sie zwei Konfigurationen gleichzeitig brauchen, dann wissen Sie sofort, dass Sie sie als Objekt instanziieren wollen, damit jedes Objekt einzigartig ist und gleichzeitig existiert.

Auf der anderen Seite eignen sich statische Funktionen eher für Aktionen, die nicht zu einem realen Objekt oder einem Objekt gehören, das man leicht darstellen kann. Denken Sie daran, dass die Vorgänger von C# C++ und C sind, wo Sie einfach globale Funktionen definieren können, die nicht in einer Klasse existieren. Dies eignet sich eher für ' Top-down ' Programmierung. Statische Methoden können für diese Fälle verwendet werden, in denen es nicht sinnvoll ist, dass ein "Objekt" die Aufgabe ausführt. Indem Sie gezwungen werden, Klassen zu verwenden, wird es einfacher, verwandte Funktionen zu gruppieren, was Ihnen hilft, einen besser wartbaren Code zu erstellen.

Die meisten Klassen können entweder statisch oder nicht statisch dargestellt werden, aber im Zweifelsfall sollten Sie sich auf Ihre OOP-Wurzeln besinnen und versuchen, sich zu überlegen, was Sie darstellen wollen. Handelt es sich um ein Objekt, das eine Aktion ausführt (ein Auto, das beschleunigen, verlangsamen oder abbiegen kann), oder um etwas Abstrakteres (z. B. die Anzeige einer Ausgabe).

Wenn Sie mit Ihrem inneren OOP in Kontakt kommen, können Sie nie etwas falsch machen!

38voto

Mark Cidade Punkte 95914

In C# 3.0 dürfen Erweiterungsmethoden nur in statischen Klassen der obersten Ebene existieren.

31voto

user25306 Punkte 411

Wenn Sie Code-Analyse-Tools verwenden (z. B. FxCop ), wird empfohlen, dass Sie eine Methode markieren static wenn diese Methode nicht auf Instanzdaten zugreift. Der Grund dafür ist, dass es einen Leistungsgewinn gibt. MSDN: CA1822 - Mitglieder als statisch markieren .

Es handelt sich eher um eine Richtlinie als um eine Regel, wirklich...

14voto

Don Punkte 729

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

Das beste Beispiel dafür ist die .Net Math-Klasse, eine statische Klasse im System-Namensraum, die eine Bibliothek mit mathematischen Funktionen enthält.

Es ist wie bei allen anderen Dingen auch: Man muss das richtige Werkzeug für die jeweilige Aufgabe verwenden, sonst kann alles missbraucht werden.

Statische Klassen pauschal als falsch abzutun, sie nicht zu verwenden oder zu sagen, "es kann nur eine" oder keine geben, ist ebenso falsch wie die übermäßige Verwendung der Klassen.

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

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

Wir haben eine statische TimeZone-Klasse, die eine Reihe von geschäftsbezogenen Zeitzonenfunktionen enthält. Es besteht keine Notwendigkeit, mehrere Instanzen der Klasse zu erstellen, so dass sie ähnlich wie die Math-Klasse eine Reihe von global zugänglichen TimeZone-bezogenen Funktionen (Methoden) in einer statischen Klasse enthält.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X