programing

C#의 기본 생성자 - 어떤 것이 먼저 호출됩니까?

javajsp 2023. 5. 29. 09:44

C#의 기본 생성자 - 어떤 것이 먼저 호출됩니까?

기본 생성자와 "여기 있는 다른 것" 중 어느 것이 먼저 호출됩니까?

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

기본 클래스 생성자는 파생 클래스 생성자보다 먼저 호출되지만 파생 클래스 초기화자는 기본 클래스 초기화자보다 먼저 호출됩니다.예: 다음 코드:

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
    }
}

실행 순서는 C, A, B, D입니다.

다음 2msdn 기사를 확인하십시오.

기본 생성자가 먼저 호출됩니다.

사용해 보십시오.

public class MyBase
{
  public MyBase()
  {
    Console.WriteLine("MyBase");
  }
}

public class MyDerived : MyBase
{
  public MyDerived():base()
  {
    Console.WriteLine("MyDerived");
  }
}

그것을 기억하려고 하지 말고, 무슨 일이 일어나야 하는지 스스로에게 설명하려고 노력하세요.동물이라는 기본 클래스와 개라는 파생 클래스가 있다고 상상해 보십시오.파생 클래스는 기본 클래스에 일부 기능을 추가합니다.따라서 파생 클래스의 생성자가 실행될 때 기본 클래스 인스턴스를 사용할 수 있어야 합니다(새 기능을 추가할 수 있음).그렇기 때문에 생성자는 기본에서 파생된 것으로 실행되지만 소멸자는 반대 방식으로 실행됩니다. 먼저 파생된 소멸자 다음에 기본 소멸자입니다.

(이 방법은 단순하지만 나중에 실제로 암기할 필요 없이 이 질문에 대답할 수 있습니다.)

실제로 파생 클래스 생성자가 먼저 실행되지만 C# 컴파일러는 기본 클래스 생성자에 대한 호출을 파생 생성자의 첫 번째 문으로 삽입합니다.

따라서 파생은 먼저 실행되지만 기본값이 먼저 실행된 것처럼 보입니다.

다른 사람들이 말했듯이, 기본 생성자가 먼저 호출됩니다.하지만, 건설업자들이 실제로 가장 먼저 일어나는 일은 아닙니다.

다음과 같은 수업이 있다고 가정해 보겠습니다.

class A {}

class B : A {}

class C : B {}

먼저 필드 이니셜라이저는 가장 많이 파생된 클래스에서 가장 적게 파생된 클래스 순으로 호출됩니다. 첫 번째 인 는저번이니이라셜드필째첫.C,그리고나서B,그리고나서A.

생성자는 반대 순서로 호출됩니다. 첫째번▁firstA에 의생자, 그다면렇.B,그리고나서C.

베이스라 할 수 있습니다.

편집:

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

거기에 다음과 같이 쓰여 있습니다.

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();
}
}

이 프로그램은 출력합니다.

베이스 2

파생 클래스

기본 생성자가 먼저 호출됩니다.그러나 파생 클래스의 필드 이니셜라이저를 먼저 호출합니다.

호출 순서는 다음과 같습니다.

  1. 파생 클래스 필드 이니셜라이저
  2. 기본 클래스 필드 이니셜라이저
  3. 기본 클래스 생성자
  4. 파생 클래스 생성자

(2와 3을 전체적으로 처리하여 기본 클래스를 구성할 수 있습니다.)

CSSharp 언어 사양 5.0에서 발췌:

10.11.3 시공자 실행

변수 이니셜라이저는 할당 문으로 변환되며, 이러한 할당 문은 기본 클래스 인스턴스 생성자가 호출되기 전에 실행됩니다.이 순서를 지정하면 해당 인스턴스에 액세스할 수 있는 문이 실행되기 전에 모든 인스턴스 필드가 변수 이니셜라이저에 의해 초기화됩니다.예를 들어,

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);
    }
}

때에new B()는 의인스만데사다니용의 를 데 됩니다.B다음 출력이 생성됩니다.

x = 1, y = 0

x변수 이니셜라이저는 기본 클래스 인스턴스 생성자가 호출되기 전에 실행되므로 1입니다. 하만가, 는치그의 y: 0(으)로 )입니다.int)에되어 있기 y기본 클래스 생성자가 반환될 때까지 실행되지 않습니다.인스턴스 변수 이니셜라이저 및 생성자 이니셜라이저를 생성자 본문 앞에 자동으로 삽입되는 문으로 생각하는 것이 유용합니다. »

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;
    }
}

에는 여러 변수 이니셜라이저가 포함되어 있으며 두 형식(기본 및 이 형식)의 생성자 이니셜라이저도 포함되어 있습니다.예제는 아래에 표시된 코드에 해당하며, 여기서 각 주석은 자동으로 삽입된 문을 나타냅니다(자동으로 삽입된 생성자 호출에 사용되는 구문은 유효하지 않지만 메커니즘을 설명하는 역할만 합니다).

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;
    }
}

Eric Lippert는 객체 초기화 관련 이슈에 대한 흥미로운 글을 올렸는데, 이는 생성자와 필드 초기화자의 주문에 대한 이유를 설명합니다.

이니시에이터가 생성자로서 반대 순서로 실행되는 이유는 무엇입니까?1부
이니시에이터가 생성자로서 반대 순서로 실행되는 이유는 무엇입니까?2부

http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=777

기본 생성자가 먼저 호출됩니다.

예외 생성자가 호출되고 하위 클래스 생성자가 호출됩니다.

간단한 OO원칙

여기를 보세요. http://www.dotnet-news.com/lien.aspx?ID=35151

기본 생성자가 먼저 호출됩니다. 그렇지 않으면 "다른 항목"이 기본 생성자에 의해 초기화된 멤버 변수를 사용해야 하는 경우 클래스 구성원이 아직 초기화되지 않았기 때문에 컴파일 시간 오류가 발생합니다.

하위 생성자에서 작업을 수행하기 전에 base(?)를 호출합니다.

이는 :base()를 생략한 경우에도 마찬가지입니다(이 경우 0-매개 변수 기본 생성자가 호출됨).

자바와 비슷하게 작동합니다.

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

예외:대신 슈퍼(1,2,3)를 넣을 수 있습니다.하지만 제가 명시적으로 superin을 호출하지 않으면 super()가 호출됩니다.

생성자 호출은 아래에서 위로 호출되고 위에서 아래로 실행됩니다.따라서 클래스 A에서 상속되는 클래스 B에서 상속되는 클래스 C가 있는 경우 클래스 C 인스턴스를 생성할 때 C에 대한 생성자가 호출되고, 이는 다시 B에 대한 강사를 호출하고, 다시 A에 대한 생성자를 호출합니다.이제 A의 생성자가 실행되고, B의 생성자가 실행되며, C의 생성자가 실행됩니다.

언급URL : https://stackoverflow.com/questions/140490/base-constructor-in-c-sharp-which-gets-called-first