cơ sở Constructor được gọi đầu tiên. Nhưng initializer của các trường trong lớp dẫn xuất được gọi là đầu tiên.
10.11.3 Constructor thực hiện
initializers biến được chuyển thành câu lệnh gán, và các báo cáo phân được thực hiện trước khi gọi các constructor dụ lớp cơ sở . Thứ tự này đảm bảo rằng tất cả các trường cá thể được khởi tạo bởi các trình khởi tạo biến của chúng trước khi bất kỳ câu lệnh nào có quyền truy cập vào cá thể đó được thực hiện. Với ví dụ
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);
}
}
khi new B()
được sử dụng để tạo ra một thể hiện của B
, các đầu ra sau đây được tạo ra:
x = 1, y = 0
Giá trị của x
là 1 vì initializer biến được thực hiện trước constructor instance của lớp cơ sở được gọi. Tuy nhiên, giá trị của y
là 0 (giá trị mặc định là int
) do việc gán đến y
không được thực hiện cho đến sau khi hàm tạo của lớp cơ sở trả về. Sẽ rất hữu ích khi nghĩ về các biến khởi tạo biến thể và các khởi tạo hàm khởi tạo như các câu lệnh được tự động chèn trước phần thân của hàm tạo. Ví dụ
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;
}
}
chứa nhiều trình khởi tạo biến; nó cũng chứa constructor initializers của cả hai form (base và this). Ví dụ tương ứng với mã được hiển thị bên dưới, trong đó mỗi nhận xét cho biết câu lệnh được chèn tự động (cú pháp được sử dụng cho lời gọi hàm xây dựng được chèn tự động không hợp lệ, nhưng chỉ phục vụ cho minh họa cơ chế).
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;
}
}
Bạn nói đúng. Nhưng việc thực thi bắt đầu từ hàm khởi tạo có nguồn gốc, điều đầu tiên mà hàm tạo có nguồn gốc thực hiện là gọi hàm tạo cơ sở (nếu có). Vì vậy, nó xuất hiện như thể các nhà xây dựng cơ sở đang được gọi là đầu tiên. –