Basiskonstruktor in C # - Welcher wird zuerst aufgerufen? [c#]


Answers

Basisklassen-Konstruktoren werden vor Konstruktoren von abgeleiteten Klassen aufgerufen, aber abgeleitete Klasseninitialisierer werden vor Basisklassen-Initialisierern aufgerufen. ZB im folgenden Code:

public class BaseClass {

    private string sentenceOne = null;  // A

    public BaseClass() {
        sentenceOne = "The quick brown fox";  // B
    }
}

public class SubClass : BaseClass {

    private string sentenceTwo = null; // C

    public SubClass() {
        sentenceTwo = "jumps over the lazy dog"; // D
    }
}

Reihenfolge der Ausführung ist: C, A, B, D.

Schauen Sie sich diese 2 msdn Artikel an:

Question

Was wird zuerst genannt - der Basiskonstrukteur oder "anderes Zeug hier"?

public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message, string extrainfo) : base(message)
    {
        //other stuff here
    }
}



Tatsächlich wird der abgeleitete Klassenkonstruktor zuerst ausgeführt, aber der C # -Compiler fügt einen Aufruf an den Basisklassenkonstruktor als erste Anweisung des abgeleiteten Konstruktors ein.

Also: der abgeleitete wird zuerst ausgeführt, aber es sieht so aus, als ob die Basis zuerst ausgeführt wurde.




Ich würde sagen, Base

EDIT siehe:

http://www.c-sharpcorner.com/UploadFile/rajeshvs/ConsNDestructorsInCS11122005010300AM/ConsNDestructorsInCS.aspx

dort heißt es:

using System;
class Base
{

public Base()
{
    Console.WriteLine("BASE 1");
}
public Base(int x)
{
    Console.WriteLine("BASE 2");
}
}

class Derived : Base
{
public Derived():base(10)
{
    Console.WriteLine("DERIVED CLASS");
}
}

class MyClient
{
public static void Main()
{
    Derived d1 = new Derived();
}
}

Dieses Programm gibt

BASE2

ABGELEITETE KLASSE







Der Basis-Konstruktor wird zuerst aufgerufen. Der Initialisierer von Feldern in der abgeleiteten Klasse wird jedoch zuerst aufgerufen.

Die Rufreihenfolge ist

  1. abgeleiteter Klassenfeld-Initialisierer
  2. Basisklasse Feldinitialisierer
  3. Basisklassen-Konstruktor
  4. Konstruktor der abgeleiteten Klasse

(Sie können 2 und 3 als Ganzes behandeln, um die Basisklasse zu erstellen.)

Aus CSharp Language Speification 5.0 entnommen :

10.11.3 Konstruktorausführung

Variableninitialisierer werden in Zuweisungsanweisungen umgewandelt, und diese Zuweisungsanweisungen werden vor dem Aufruf des Instanzkonstruktors der Basisklasse ausgeführt. Diese Reihenfolge stellt sicher, dass alle Instanzfelder durch ihre Variableninitialisierer initialisiert werden, bevor alle Anweisungen ausgeführt werden, die Zugriff auf diese Instanz haben. Angesichts des Beispiels

using System;
class A
{
    public A() {
        PrintFields();
    }
    public virtual void PrintFields() {}
}
class B: A
{
    int x = 1;
    int y;
    public B() {
        y = -1;
    }
    public override void PrintFields() {
        Console.WriteLine("x = {0}, y = {1}", x, y);
    }
}

Wenn new B() verwendet wird, um eine Instanz von B zu erstellen, wird die folgende Ausgabe erzeugt:

x = 1, y = 0

Der Wert von x ist 1, da der Variableninitialisierer ausgeführt wird, bevor der Basisklasseninstanzkonstruktor aufgerufen wird. Der Wert von y ist jedoch 0 (der Standardwert von int ), da die Zuweisung zu y erst ausgeführt wird, nachdem der Basisklassenkonstruktor zurückgegeben wurde. Es ist hilfreich, sich Instanzenvariablen-Initialisierer und Konstruktorinitialisierer als Anweisungen vorzustellen, die vor dem Konstruktorkörper automatisch eingefügt werden. Das Beispiel

using System;
using System.Collections;
class A
{
    int x = 1, y = -1, count;
    public A() {
        count = 0;
    }
    public A(int n) {
        count = n;
    }
}
class B: A
{
    double sqrt2 = Math.Sqrt(2.0);
    ArrayList items = new ArrayList(100);
    int max;
    public B(): this(100) {
        items.Add("default");
    }
    public B(int n): base(n  1) {
        max = n;
    }
}

enthält mehrere Variablen-Initialisierer; Es enthält auch Konstruktorinitialisierer beider Formen (Basis und this). Das Beispiel entspricht dem unten gezeigten Code, wobei jeder Kommentar auf eine automatisch eingefügte Anweisung hinweist (die Syntax, die für die automatisch eingefügten Konstruktoraufrufe verwendet wird, ist nicht gültig, dient aber lediglich zur Veranschaulichung des Mechanismus).

using System.Collections;
class A
{
    int x, y, count;
    public A() {
        x = 1;                                // Variable initializer
        y = -1;                               // Variable initializer
        object();                         // Invoke object() constructor
        count = 0;
    }
    public A(int n) {
        x = 1;                                // Variable initializer
        y = -1;                               // Variable initializer
        object();                         // Invoke object() constructor
        count = n;
    }
}
class B: A
{
    double sqrt2;
    ArrayList items;
    int max;
    public B(): this(100) {
        B(100);                               // Invoke B(int) constructor
        items.Add("default");
    }
    public B(int n): base(n  1) {
        sqrt2 = Math.Sqrt(2.0);           // Variable initializer
        items = new ArrayList(100);   // Variable initializer
        A(n  1);                         // Invoke A(int) constructor
        max = n;
    }
}



base (?) wird aufgerufen, bevor im untergeordneten Konstruktor eine Arbeit ausgeführt wird.

Das ist wahr, auch wenn Sie die: base () -Funktion verlassen (in diesem Fall wird der 0-Parameter-Basiskonstruktor aufgerufen).

Es funktioniert ähnlich wie Java,

public Child()
{
   super(); // this line is always the first line in a child constructor even if you don't put it there! ***
}

*** Ausnahme: Ich könnte stattdessen super (1,2,3) einsetzen. Aber wenn ich nicht explizit einen Aufruf an super herstelle, wird super () aufgerufen.