385 Stimmen

Was ist der Zweck von statischen Konstruktoren?

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?

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.

5voto

Kenny Evitt Punkte 8632

Warum und wann würden wir einen statischen Konstruktor erstellen ...?

Ein spezifischer Grund, um einen statischen Konstruktor zu verwenden, besteht darin, eine 'Super-Enum'-Klasse zu erstellen. Hier ist ein (einfaches, konstruiertes) Beispiel:

public class Tiere
{
    private readonly string _beschreibung;
    private readonly string _artBinomName;

    public string Beschreibung { get { return _beschreibung; } }
    public string ArtBinomName { get { return _artBinomName; } }

    private Tiere(string beschreibung, string artBinomName)
    {
        _beschreibung = beschreibung;
        _artBinomName = artBinomName;
    }

    private static readonly Tiere _hund;
    private static readonly Tiere _katze;
    private static readonly Tiere _boaconstrictor;

    public static Tiere Hund { get { return _hund; } }
    public static Tiere Katze { get { return _katze; } }
    public static Tiere BoaConstrictor { get { return _boaconstrictor; } }

    static Tiere()
    {
        _hund = new Tiere("Der beste Freund des Menschen", "Canis familiaris");
        _katze = new Tiere("Kleiner, typischerweise pelziger Killer", "Felis catus");
        _boaconstrictor = new Tiere("Große, schwer gebaute Schlange", "Boa constrictor");
    }
}

Sie würden es sehr ähnlich verwenden (im syntaktischen Erscheinungsbild) wie jedes andere Enum:

Tiere.Hund

Der Vorteil gegenüber einem regulären enum ist, dass Sie verwandte Informationen leicht kapseln können. Ein Nachteil ist, dass Sie diese Werte nicht in einer switch-Anweisung verwenden können (weil sie konstante Werte erfordert).

3voto

Hasan Fathi Punkte 4840

Statischer Konstruktor wird nur beim Erstellen der ersten Instanz der Klasse aufgerufen und wird verwendet, um eine bestimmte Aktion auszuführen, die nur einmal im Lebenszyklus der Klasse ausgeführt werden muss.

3voto

Joma Punkte 2432

Von der Microsoft-Dokumentation https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors

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. Er wird automatisch aufgerufen, bevor die erste Instanz erstellt oder auf statische Member verwiesen wird.

class SimpleClass
{
    // Statische Variable, die zur Laufzeit initialisiert werden muss.
    static readonly long baseline;

    // Der statische Konstruktor wird höchstens einmal aufgerufen, bevor ein
    // Instanzkonstruktor aufgerufen oder auf ein Member zugegriffen wird.
    static SimpleClass()
    {
        baseline = DateTime.Now.Ticks;
    }
}

Bemerkungen

Statische Konstruktoren haben folgende Eigenschaften:

  • Ein statischer Konstruktor hat keine Zugriffsmodifizierer oder Parameter.
  • Eine Klasse oder Struktur kann nur einen statischen Konstruktor haben.
  • Statische Konstruktoren können nicht vererbt oder überladen werden.
  • Ein statischer Konstruktor kann nicht direkt aufgerufen werden und ist nur dazu gedacht, vom Common Language Runtime (CLR) aufgerufen zu werden. Er wird automatisch aufgerufen.
  • Der Benutzer hat keine Kontrolle darüber, wann der statische Konstruktor im Programm ausgeführt wird.
  • Ein statischer Konstruktor wird automatisch aufgerufen. Er initialisiert die Klasse, bevor die erste Instanz erstellt wird oder auf statische Member verwiesen wird, die in dieser Klasse deklariert sind (nicht in ihren Basisklassen). Ein statischer Konstruktor wird vor einem Instanzkonstruktor ausgeführt. Der statische Konstruktor einer Typs wird aufgerufen, wenn eine statische Methode, die einem Ereignis oder einem Delegaten zugewiesen ist, aufgerufen wird und nicht, wenn sie zugewiesen wird. Wenn statische Feldvariableninitialisierer in der Klasse des statischen Konstruktors vorhanden sind, werden sie in der textuellen Reihenfolge ausgeführt, in der sie in der Klassendeklaration erscheinen. Die Initialisierer werden unmittelbar vor der Ausführung des statischen Konstruktors ausgeführt.
  • Wenn Sie keinen statischen Konstruktor bereitstellen, um statische Felder zu initialisieren, werden alle statischen Felder auf ihren Standardwert initialisiert, wie in den Standardwerten von C#-Typen aufgeführt.
  • Wenn ein statischer Konstruktor eine Ausnahme auslöst, ruft die Laufzeit diesen nicht ein zweites Mal auf, und der Typ bleibt für die Lebensdauer der Anwendungsdomäne uninitialisiert. In der Regel wird eine xref:System.TypeInitializationException-Ausnahme ausgelöst, wenn ein statischer Konstruktor nicht in der Lage ist, einen Typ zu instanziieren oder eine unbehandelte Ausnahme innerhalb eines statischen Konstruktors auftritt. Zum Troubleshooting von statischen Konstruktoren, die nicht explizit im Quellcode definiert sind, ist möglicherweise Inspektion des Intermediate Language (IL)-Codes erforderlich.
  • Die Anwesenheit eines statischen Konstruktors verhindert die Hinzufügung des xref:System.Reflection.TypeAttributes.BeforeFieldInit-Typattributs. Dies begrenzt die Laufzeitoptimierung.
  • Ein als static readonly deklariertes Feld darf nur als Teil seiner Deklaration oder in einem statischen Konstruktor zugewiesen werden. Wenn kein expliziter statischer Konstruktor erforderlich ist, initialisieren Sie statische Felder bei der Deklaration und nicht über einen statischen Konstruktor für eine bessere Laufzeitoptimierung.
  • Die Laufzeit ruft einen statischen Konstruktor höchstens einmal in einer einzelnen Anwendungsdomäne auf. Dieser Aufruf erfolgt in einem gesperrten Bereich, der auf dem spezifischen Typ der Klasse basiert. Im Rumpf eines statischen Konstruktors sind keine zusätzlichen Sperrmechanismen erforderlich. Um das Risiko von Deadlocks zu vermeiden, blockieren Sie den aktuellen Thread nicht in statischen Konstruktoren und Initialisierern. Warten Sie beispielsweise nicht auf Aufgaben, Threads, Warteschleifen oder Ereignisse, erlangen Sie keine Sperren und führen Sie keine blockierenden parallelen Operationen wie parallele Schleifen, Parallel.Invoke und Parallel LINQ-Abfragen aus.

[!Hinweis] Obwohl nicht direkt zugänglich, sollte die Anwesenheit eines expliziten statischen Konstruktors dokumentiert werden, um bei der Fehlerbehebung von Initialisierungsfehlern zu helfen.

Verwendung

  • Ein typischer Einsatz von statischen Konstruktoren besteht darin, dass die Klasse eine Protokolldatei 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, wobei der Konstruktor die Methode LoadLibrary aufrufen kann.
  • Statische Konstruktoren sind auch ein geeigneter Ort, um Laufzeitprüfungen für den Typparameter durchzuführen, die nicht über Typparameterbeschränkungen zur Kompilierzeit überprüft werden können.

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