Bitte erkläre mir die Verwendung eines statischen Konstruktors. Warum und wann würden wir einen statischen Konstruktor erstellen und ist es möglich, einen zu überladen?
Antworten
Zu viele Anzeigen?Nein, du kannst es nicht überladen; ein statischer Konstruktor ist nützlich zum Initialisieren von statischen Feldern, die mit einem Typ verbunden sind (oder anderen operationen pro Typ) - nützlich insbesondere zum Lesen von erforderlichen Konfigurationsdaten in readonly-Feldern usw.
Es wird automatisch vom Laufzeitsystem das erste Mal ausgeführt, wenn es benötigt wird (die genauen Regeln sind kompliziert (siehe "beforefieldinit"), und veränderten sich subtil zwischen CLR2 und CLR4). Es ist garantiert, dass es höchstens einmal ausgeführt wird (auch wenn zwei Threads gleichzeitig kommen), es sei denn, du missbrauchst Reflection.
Aus Statische Konstruktoren (C# Programming Guide):
Ein statischer Konstruktor wird verwendet, um alle statischen Daten zu initialisieren oder um eine bestimmte Aktion durchzuführen, die nur einmal ausgeführt werden muss. Er wird automatisch aufgerufen, bevor die erste Instanz erstellt wird oder auf statische Member verwiesen wird.
Statische Konstruktoren haben folgende Eigenschaften:
Ein statischer Konstruktor hat keine Zugriffsmodifizierer oder Parameter.
Ein statischer Konstruktor wird automatisch aufgerufen, um die Klasse zu initialisieren, bevor die erste Instanz erstellt wird oder auf statische Member verwiesen wird.
Ein statischer Konstruktor kann nicht direkt aufgerufen werden.
Der Benutzer hat keine Kontrolle darüber, wann der statische Konstruktor im Programm ausgeführt wird.
Eine typische Verwendung von statischen Konstruktoren besteht darin, wenn die Klasse eine Logdatei verwendet und der Konstruktor verwendet wird, um Einträge in diese Datei zu schreiben.
Statische Konstruktoren sind auch nützlich, wenn Wrapper-Klassen für nicht verwalteten Code erstellt werden, wenn der Konstruktor die Methode
LoadLibrary
aufrufen kann.
Statische Konstruktoren sind auch sehr nützlich, wenn Sie statische Felder haben, die voneinander abhängig sind, so dass die Reihenfolge der Initialisierung wichtig ist. Wenn Sie Ihren Code durch einen Formatter/Beautifier laufen lassen, der die Reihenfolge der Felder ändert, könnten Sie sich mit Nullwerten konfrontiert sehen, wo Sie sie nicht erwartet haben.
Beispiel: Angenommen, wir hätten diese Klasse:
class ScopeMonitor
{
static string urlFragment = "foo/bar";
static string firstPart= "http://www.example.com/";
static string fullUrl= firstPart + urlFragment;
}
Wenn Sie auf fullUr
zugreifen, wird es "http://www.example.com/foo/bar" sein.
Monate später reinigen Sie Ihren Code und sortieren die Felder alphabetisch (sagen wir, sie sind Teil einer viel größeren Liste, sodass Sie das Problem nicht bemerken). Sie haben:
class ScopeMonitor
{
static string firstPart= "http://www.example.com/";
static string fullUrl= firstPart + urlFragment;
static string urlFragment = "foo/bar";
}
Ihr fullUrl
Wert ist nun nur noch "http://www.example.com/", da urlFragment
zum Zeitpunkt der Festlegung von fullUrl
nicht initialisiert war. Nicht gut. Also fügen Sie einen statischen Konstruktor hinzu, um die Initialisierung zu übernehmen:
class ScopeMonitor
{
static string firstPart= "http://www.example.com/";
static string fullUrl;
static string urlFragment = "foo/bar";
static ScopeMonitor()
{
fullUrl= firstPart + urlFragment;
}
}
Jetzt wird die Initialisierung immer korrekt sein, unabhängig von der Reihenfolge der Felder.
1.Es kann nur auf das/die statische(n) Element(e) der Klasse zugreifen.
Grund: Nicht statische Elemente sind spezifisch für die Objektinstanz. Wenn statische Konstruktoren Zugriff auf nicht statische Elemente hätten, würden sich die Änderungen in allen Objektinstanzen widerspiegeln, was unpraktisch wäre.
2.Es sollten keine Parameter im statischen Konstruktor sein.
Grund: Da er vom CLR aufgerufen wird, kann niemand Parameter an ihn übergeben. 3.Nur ein statischer Konstruktor ist erlaubt.
Grund: Überladen erfordert, dass die beiden Methoden in Bezug auf die Methoden-/Konstruktordefinition unterschiedlich sind, was im statischen Konstruktor nicht möglich ist.
4.Es sollte kein Zugriffsmodifizierer dazu geben.
Grund: Auch hier wird der statische Konstruktor vom CLR und nicht vom Objekt aufgerufen, daher ist es nicht erforderlich, einen Zugriffsmodifizierer dafür zu haben
Sie können den statischen Konstruktor verwenden, um statische Felder zu initialisieren. Er wird zu einem unbestimmten Zeitpunkt vor der Verwendung dieser Felder ausgeführt. Die Dokumentation von Microsoft und viele Entwickler warnen davor, dass statische Konstruktoren eines Typs einen erheblichen Overhead verursachen.
Es ist am besten, statische Konstruktoren für maximale Leistung zu vermeiden.
Update: Sie können nicht mehr als einen statischen Konstruktor in derselben Klasse verwenden, jedoch können Sie andere Instanzkonstruktoren mit (höchstens) einem statischen Konstruktor verwenden.
- See previous answers
- Weitere Antworten anzeigen
4 Stimmen
Es sei darauf hingewiesen, dass es statische Konstruktionsmethoden gibt (beispielsweise das Singleton Design Pattern), die dazu dienen, die tatsächlichen Konstruktoren des Klasseninstanziierung zu verbergen. Dies gibt dem Autor mehr Kontrolle darüber, wie ihre Klasse verwendet wird.