Konstruktorverkettung in C#

Fil Zjazel Romaeus Villegas 12 Oktober 2023
  1. Was ist ein Konstruktor?
  2. Was ist Konstruktorüberladung?
  3. Was ist Konstruktorverkettung?
  4. Beispiel für Konstruktorverkettung
Konstruktorverkettung in C#

Dieses Tutorial zeigt, wie man Konstruktorverkettung in C# durchführt. Um Constructor Chaining zu verstehen, müssen Sie zunächst die folgenden Konzepte kennen.

Was ist ein Konstruktor?

Ein Konstruktor ist eine Methode in einer Klasse, die automatisch ausgeführt wird, wenn ein Objekt erstellt wird. Der Konstruktor kann leer gelassen werden oder auch verschiedene Anweisungen und Schritte enthalten, die befolgt werden, wenn eine neue Instanz erstellt wird.

Betrachten Sie diese Beispielklasse unten. Der Konstruktor dieser Klasse setzt bei der Initialisierung automatisch die Werte seiner Variablen wie unten beschrieben. Wenn Sie den Konstruktor leer lassen, sind stattdessen alle Klassenvariablen standardmäßig null.

class Tutorial_Class {
  public string name;
  public DateTime created_date;
  public List<string> topics;
  public string description;
  public bool draft;

  public Tutorial_Class() {
    // This is the constructor method
    this.name = "Tutorial Draft";
    this.created_date = DateTime.Now;
    this.topics = new List<string>();
    this.description = "Tutorial Description";
    this.draft = true;
  }
}

Was ist Konstruktorüberladung?

Konstruktorüberladung ermöglicht es Ihnen, basierend auf den Eingabeparametern, die Sie beim Erstellen einer neuen Instanz der Klasse bereitgestellt haben, einen anderen Konstruktor aufzurufen. Für jedes akzeptierte Parameterszenario müssen Sie den zu verwendenden Konstruktor definieren. Sie können beliebig viele Konstruktorüberladungen haben.

Im folgenden Beispiel haben wir eine weitere Konstruktorfunktion hinzugefügt, die eine einzelne Zeichenfolgeneingabe akzeptiert. Wenn eine Eingabe bereitgestellt wird, wird die Namensvariable auf den Eingabewert gesetzt.

class Tutorial_Class {
  public string name;
  public DateTime created_date;
  public List<string> topics;
  public string description;
  public bool draft;

  public Tutorial_Class() {
    // This is the initial constructor method and will be used if no parameter is passed
    this.name = "Tutorial Draft";
    this.created_date = DateTime.Now;
    this.topics = new List<string>();
    this.description = "Tutorial Description";
    this.draft = true;
  }

  public Tutorial_Class(string name) {
    // This is the second constructor method and will be used if you pass a single string parameter
    // Instead of the name variable being set to "Tutorial Draft", it will be set to the value of
    // the input parameter
    this.name = name;
    this.created_date = DateTime.Now;
    this.topics = new List<string>();
    this.description = "Tutorial Description";
    this.draft = true;
  }
}

Was ist Konstruktorverkettung?

Konstruktorverkettung ermöglicht es Ihnen, einen anderen Konstruktor innerhalb eines anderen aufzurufen. Angenommen, Sie erstellen anhand des gleichen Beispiels eine neue Instanz von Tutorial_Class, ohne Parameter zu übergeben. Wir können den anfänglichen Konstruktor so ändern, dass er einen Standardparameter hat, der den zweiten aufzurufenden Konstruktor auslöst. Daher der Name Constructor Chaining. Sie können es sich auch ähnlich wie optionale Argumente vorstellen, die einen Standardwert festlegen, unabhängig davon, ob Sie explizit etwas übergeben haben.

Im folgenden Beispiel übergeben wir, anstatt die Werte im anfänglichen Konstruktor festzulegen, den Standardnamen Tutorial Draft an den Konstruktor, der den zweiten Konstruktor auslöst.

class Tutorial_Class {
  public string name;
  public DateTime created_date;
  public List<string> topics;
  public string description;
  public bool draft;

  public Tutorial_Class() : this("Tutorial Draft") {
    // The intiial constructor is now blank but will trigger the second constructor due to the
    // "this("Tutorial Draft")" line.
    // If you remove the parameter, all of the class variables will again be null by default instead
  }

  public Tutorial_Class(string name) {
    // As the initial constructor passed a single string parameter, this constructor is then called
    // and all variable values are set
    this.name = name;
    this.created_date = DateTime.Now;
    this.topics = new List<string>();
    this.description = "Tutorial Description";
    this.draft = true;
  }
}

Beispiel für Konstruktorverkettung

Unter Verwendung der oben diskutierten Konzepte können wir dann Konstruktorverkettung anwenden und sehen, wie sich die Klasse in Abhängigkeit von den verschiedenen Eingaben verhält.

Beispiel:

using System;
using System.Collections.Generic;

namespace ConstructorChaining_Example {
  class Program {
    static void Main(string[] args) {
      // Initialize a new instance of the class with no parameters
      Tutorial_Class no_params = new Tutorial_Class();
      // Print the results to the console
      Console.WriteLine("Tutorial_Class with No Parameters:\n");
      PrintVariables(no_params);

      // Initialize a new instance of the class with the tutorial name "Sample Tutorial 1"
      Tutorial_Class string_param = new Tutorial_Class("Sample Tutorial 1");
      // Print the results to the console
      Console.WriteLine("Tutorial_Class with a Tutorial Name Provided:\n");
      PrintVariables(string_param);

      // Initialize a new instance of the class with the tutorial name "Sample Tutorial 2" and a
      // created date of December 31, 2021.
      Tutorial_Class string_and_date_param =
          new Tutorial_Class("Sample Tutorial 2", new DateTime(2021, 12, 31));
      // Print the results to the console
      Console.WriteLine("Tutorial_Class with a Tutorial Name and Created Date Provided:\n");
      PrintVariables(string_and_date_param);

      Console.ReadLine();
    }

    public class Tutorial_Class {
      public string name;
      public DateTime created_date;
      public List<string> topics;
      public string description;
      public bool draft;

      public Tutorial_Class() : this("Tutorial Draft") {
        // This is the initial constructor class which is only executed when no parameters are
        // passed Once the class is created, the second constructor class will be triggered with the
        // name parameter "Tutorial Draft"
        this.description = "No Parameter Passed";
      }

      public Tutorial_Class(string name) : this(name, DateTime.Now) {
        // This is the second constructor class
        // This can be called by two ways, either by initializing the class with no parameters or by
        // passing a specific string parameter for the tutorial name Regardless of how this
        // constructor is triggered, it will by default also execute the third constructor class by
        // passing the current DateTime as the date param
        this.description = "A tutorial name has been passed";
      }

      public Tutorial_Class(string name, DateTime date) {
        // This is the third constructor class
        // Regardless of how the class is initialized, this will always be triggered due to how the
        // constructors are chained
        this.name = name;
        this.created_date = date;
        this.topics = new List<string>();
        this.description = "A tutorial name and created date have both been passed";
        this.draft = true;
      }
    }

    public static void PrintVariables(Tutorial_Class tutorial) {
      // This function accepts a Tutorial_Class and prints three of its variables to the console
      Console.WriteLine("Tutorial Name: " + tutorial.name + "\n");
      Console.WriteLine("Created Date: " + tutorial.created_date.ToString() + "\n");
      Console.WriteLine("Description: " + tutorial.description + "\n");

      Console.WriteLine("\n");
    }
  }
}

Im obigen Beispiel haben wir drei Instanzen der Tutorial_Class erstellt und jeder unterschiedliche Parameter bereitgestellt. Sie können beobachten, dass unabhängig davon, welcher Konstruktor zuerst initialisiert wurde, immer noch der dritte Konstruktor ausgelöst wurde, was überprüft werden kann, indem Sie sehen, dass die anderen Variablen auch Werte haben, nicht nur die Beschreibung.

Eine weitere wichtige Sache, die zu beachten ist, ist, dass die verketteten Konstruktoren zuerst aufgerufen werden, bevor die Anweisungen in ihrem Hauptkonstruktor ausgeführt werden. Dies ist durch die Beschreibungsvariable ersichtlich, die je nachdem, welche Parameter ursprünglich bereitgestellt wurden, unterschiedlich ist.

Ausgabe:

Tutorial_Class with No Parameters:

Tutorial Name: Tutorial Draft

Created Date: 28/12/2021 8:25:35 pm

Description: No Parameter Passed



Tutorial_Class with a Tutorial Name Provided:

Tutorial Name: Sample Tutorial 1

Created Date: 28/12/2021 8:25:35 pm

Description: A tutorial name has been passed



Tutorial_Class with a Tutorial Name and Created Date Provided:

Tutorial Name: Sample Tutorial 2

Created Date: 31/12/2021 12:00:00 am

Description: A tutorial name and created date have both been passed