wake-up-neo.com

Was ist die Verwendung von statischen Konstruktoren?

Bitte erklären Sie mir die Verwendung des statischen Konstruktors. Warum und wann würden wir einen statischen Konstruktor erstellen und ist es möglich, einen zu überladen?

280

Nein, Sie können es nicht überlasten. Ein statischer Konstruktor ist nützlich, um statische Felder zu initialisieren, die einem Typ (oder anderen typspezifischen Operationen) zugeordnet sind. Dies ist insbesondere nützlich, um erforderliche Konfigurationsdaten in schreibgeschützte Felder usw. zu lesen.

Es wird von der Laufzeit automatisch ausgeführt, wenn es zum ersten Mal benötigt wird (die genauen Regeln dort sind kompliziert (siehe "beforeefieldinit") und zwischen CLR2 und CLR4 subtil geändert). Wenn Sie die Reflektion nicht missbrauchen, wird sie garantiert höchstens einmal ausgeführt (auch wenn zwei Threads gleichzeitig eintreffen).

240
Marc Gravell

From Statische Konstruktoren (C # -Programmierhandbuch) :

Ein statischer Konstruktor wird verwendet, um statische Daten zu initialisieren oder eine bestimmte Aktion auszuführen, die nur einmal ausgeführt werden muss. Es wird automatisch aufgerufen, bevor die erste Instanz erstellt wird oder auf statische Elemente verwiesen wird.

Statische Konstruktoren haben folgende Eigenschaften:

  • Ein statischer Konstruktor verwendet keine Zugriffsmodifikatoren 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 ist, wenn die Klasse eine Protokolldatei verwendet und der Konstruktor zum Schreiben von Einträgen in diese Datei verwendet wird.

  • Statische Konstruktoren sind auch beim Erstellen von Wrapperklassen für nicht verwalteten Code hilfreich, wenn der Konstruktor die Methode LoadLibrary aufrufen kann.

110
Adriaan Stander

Statische Konstruktoren sind auch sehr nützlich, wenn Sie statische Felder haben, die aufeinander angewiesen sind, sodass die Reihenfolge der Initialisierung wichtig ist. Wenn Sie Ihren Code über einen Formatierer/Verschönerer ausführen, der die Reihenfolge der Felder ändert, werden Sie möglicherweise mit Nullwerten konfrontiert, mit denen Sie nicht gerechnet haben.

Beispiel: Angenommen, wir hatten 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 " http://www.example.com/foo/bar " angezeigt.

Monate später bereinigen Sie Ihren Code und alphabetisieren die Felder (sagen wir, sie sind Teil einer viel größeren Liste, damit Sie das Problem nicht bemerken). Du hast:

class ScopeMonitor
{
    static string firstPart= "http://www.example.com/";
    static string fullUrl= firstPart + urlFragment;
    static string urlFragment = "foo/bar";
}

Ihr fullUrl Wert ist jetzt nur " http://www.example.com/ ", da urlFragment zu dem Zeitpunkt nicht initialisiert wurde fullUrl wurde eingestellt. Nicht gut. Sie fügen also einen statischen Konstruktor hinzu, der sich um die Initialisierung kümmert:

class ScopeMonitor
{
    static string firstPart= "http://www.example.com/";
    static string fullUrl;
    static string urlFragment = "foo/bar";

    static ScopeMonitor()
    {
        fullUrl= firstPart + urlFragment;

    }
}

Egal in welcher Reihenfolge Sie die Felder haben, die Initialisierung ist immer korrekt.

91
Mark Meuer

1. Es kann nur auf die statischen Member der Klasse zugegriffen werden.

Grund: Ein nicht statisches Element ist spezifisch für die Objektinstanz. Wenn der statische Konstruktor an nicht statischen Elementen arbeiten darf, werden die Änderungen in der gesamten Objektinstanz berücksichtigt, was nicht praktikabel ist.

2.Der statische Konstruktor darf keine Parameter enthalten.

Grund: Da es von CLR aufgerufen wird, kann niemand den Parameter übergeben. 3. Es ist nur ein statischer Konstruktor zulässig.

Grund: Beim Überladen müssen sich die beiden Methoden in Bezug auf die Methoden-/Konstruktordefinition unterscheiden, was im statischen Konstruktor nicht möglich ist.

4. Es sollte keinen Zugriffsmodifikator dafür geben.

Grund: Wiederum ist der Grund, dass der gleiche Aufruf des statischen Konstruktors durch CLR und nicht durch das Objekt erfolgt und kein Zugriffsmodifikator erforderlich ist

14
ravithejag

sie können den statischen Konstruktor verwenden, um statische Felder zu initialisieren. Es wird zu einem unbestimmten Zeitpunkt ausgeführt, bevor diese Felder verwendet werden. Die Dokumentation von Microsoft und viele Entwickler warnen, dass statische Konstruktoren für einen Typ einen erheblichen Mehraufwand bedeuten.
Vermeiden Sie statische Konstruktoren, um eine maximale Leistung zu erzielen.
aktualisieren: Sie können nicht mehr als einen statischen Konstruktor in derselben Klasse verwenden, Sie können jedoch andere Instanzkonstruktoren mit (maximal) einem statischen Konstruktor verwenden.

9
Dot Freelancer

Warum und wann sollten wir einen statischen Konstruktor erstellen ...?

Ein spezifischer Grund für die Verwendung eines statischen Konstruktors ist das Erstellen einer Klasse 'super enum'. Hier ist ein (einfaches, ausgedachtes) Beispiel:

public class Animals
{
    private readonly string _description;
    private readonly string _speciesBinomialName;

    public string Description { get { return _description; } }
    public string SpeciesBinomialName { get { return _speciesBinomialName; } }

    private Animals(string description, string speciesBinomialName)
    {
        _description = description;
        _speciesBinomialName = speciesBinomialName;
    }

    private static readonly Animals _dog;
    private static readonly Animals _cat;
    private static readonly Animals _boaConstrictor;

    public static Animals Dog { get { return _dog; } }
    public static Animals Cat { get { return _cat; } }
    public static Animals BoaConstrictor { get { return _boaConstrictor; } }

    static Animals()
    {
        _dog = new Animals("Man's best friend", "Canis familiaris");
        _cat = new Animals("Small, typically furry, killer", "Felis catus");
        _boaConstrictor = new Animals("Large, heavy-bodied snake", "Boa constrictor");
    }
}

Sie würden es sehr ähnlich (syntaktisch gesehen) wie jede andere Aufzählung verwenden:

Animals.Dog

Dies hat gegenüber einem normalen enum den Vorteil, dass Sie verwandte Informationen einfach kapseln können. Ein Nachteil ist, dass Sie diese Werte nicht in einer switch -Anweisung verwenden können (da dafür konstante Werte erforderlich sind).

5
Kenny Evitt

Statischer Konstruktor

Ein Konstruktor, der mit dem statischen Modifikator deklariert wurde, ist ein statischer Konstruktor. Ein statischer Konstruktor wird zum Initialisieren statischer Daten oder zum Ausführen einer bestimmten Aktion verwendet, die nur einmal im Lebenszyklus einer Klasse ausgeführt werden muss. Der statische Konstruktor ist der erste Codeblock, der in der Klasse ausgeführt wird. Der statische Konstruktor wird nur einmal im Lebenszyklus einer Klasse ausgeführt. Es wird automatisch aufgerufen. Der statische Konstruktor akzeptiert keine Parameter. Es hat keine Zugriffsspezifizierer. Es wird nicht direkt aufgerufen.

2
Hasan Fathi