Tạo trình tạo lớp và tạo đối tượng
Ngoài các thuộc tính lớp và phương pháp, lớp định nghĩa bao gồm các nhà xây dựng được sử dụng để khởi tạo các đối tượng mới (lớp thể hiện).
Trình tạo lớp
Hàm tạo lớp là một phương pháp có cùng tên với loại (phương pháp hàm tạo sử dụng cùng tên với lớp).
Có hai loại trình xây dựng lớp:
- Trình xây dựng phiên bản. Hàm tạo phiên bản được sử dụng để tạo và khởi tạo bất kỳ biến trường thể hiện nào khi một đối tượng được tạo.
- Hàm tạo tĩnh. Hàm tạo tĩnh được sử dụng để khởi tạo bất kỳ dữ liệu tĩnh nào hoặc để thực hiện một hành động cụ thể chỉ cần thực hiện một lần. Hàm tạo tĩnh được gọi tự động trước khi phiên bản đầu tiên được tạo hoặc bất kỳ thành viên tĩnh nào được tham chiếu.
Trình tạo lớp là trình tạo phiên bản theo mặc định.
Cú pháp hàm dựng thể hiện
Hàm tạo phiên bản được khai báo sử dụng cùng tên với lớp và không bao gồm kiểu trả về. Chữ ký phương thức của hàm tạo có thể bao gồm bổ trợ truy nhập tùy chọn, tên phương thức và danh sách tham số của nó. Chữ ký phương thức của hàm tạo không bao gồm kiểu trả về.
Ví dụ sau đây cho thấy một hàm tạo đơn giản cho một lớp có tên Person:
public class Person
{
public Person()
{
// Field initialization and constructor logic goes here.
}
// Remaining implementation of Person class.
}
Lớp có thể có nhiều hơn một hàm dựng. Khi một lớp có nhiều hàm dựng, hàm dựng thường lấy các tham đối khác nhau.
Ví dụ sau đây cho thấy một lớp có tên Person với hai hàm tạo.
public class Person
{
public Person()
{
// Field initialization and constructor logic goes here.
string name = "Person One";
Console.WriteLine($"Person created: {name}");
}
public Person(string fName, string lName)
{
string name = fName + " " + lName;
Console.WriteLine($"Person created: {name}");
}
// Remaining implementation of Person class.
}
Tạo đối tượng tức thời bằng cách sử dụng trình tạo lớp
Khi đối tượng được tạo đối tượng bằng cách sử dụng từ khóa new, thời gian chạy .NET gọi hàm tạo phiên bản liên quan trong định nghĩa lớp và phân bổ bộ nhớ cho đối tượng.
Trong đoạn mã sau đây, lớp Person xác định hàm tạo phiên bản đơn giản. Lớp Program bao gồm một phương pháp Main sử dụng toán tử new để tạo một thể hiện của Person tên là person1. Thời gian chạy gọi bộ cấu trúc Person lập tức sau khi bộ nhớ được phân bổ cho đối tượng mới.
public class Person
{
public Person()
{
// Field initialization and constructor logic goes here.
}
}
static class Program
{
// the Main method is the entry point of the program.
static void Main()
{
Person person1 = new Person();
}
}
Hàm tạo có và không có tham số
Hàm tạo không có tham số được gọi là hàm tạo không tham số. Thời gian chạy gọi hàm tạo không tham số khi một đối tượng được tạo đối tượng bằng cách sử dụng toán tử new và không có đối số nào được cung cấp cho hàm tạo.
Ghi
Trừ khi lớp là tĩnh, các lớp không có hàm tạo được trình tạo không tham số công cộng cung cấp bởi trình biên dịch C# để cho phép thuyết trình lớp.
Các lớp thường xác định hàm tạo lấy tham số. Hàm tạo lấy tham số phải được gọi bằng cách sử dụng toán new hoặc câu lệnh cơ sở. Lớp có thể xác định một hoặc nhiều hàm xây dựng.
Đoạn mã sau đây hiển thị một lớp có tên là Person ba hàm tạo:
public class Person
{
public Person()
{
// Field initialization and constructor logic goes here.
Console.WriteLine("An instance of the Person class is being instantiated without name or age parameters.");
}
public Person(string name)
{
// Field initialization and constructor logic goes here.
Console.WriteLine($"An instance of the Person class is being instantiated using a name ({name}) parameter.");
}
public Person(string name, int age)
{
// Field initialization and constructor logic goes here.
Console.WriteLine($"An instance of the Person class is being instantiated using name ({name}) and age ({age}) parameters.");
}
}
static class Program
{
// the Main method is the entry point of the program.
static void Main()
{
Person person1 = new Person();
Person person2 = new Person("Person Two");
Person person3 = new Person("Person Three", 30);
}
}
Các lớp không có hàm tạo
Nếu một lớp không có hàm tạo thể hiện rõ ràng, C# cung cấp một hàm tạo không tham số mà bạn có thể sử dụng để tạo phiên bản của lớp đó, như ví dụ sau đây cho thấy:
public class Person
{
public int age;
public string name = "unknown";
}
class Example
{
static void Main()
{
var person = new Person();
Console.WriteLine($"Name: {person.name}, Age: {person.age}");
// Output: Name: unknown, Age: 0
}
}
Hàm dựng này khởi tạo các trường và thuộc tính phiên bản theo các bộ khởi tạo tương ứng. Nếu một trường hoặc thuộc tính không có bộ khởi tạo, giá trị của trường hoặc thuộc tính đó được đặt thành giá trị mặc định của loại trường hoặc thuộc tính. Nếu bạn khai báo ít nhất một hàm tạo phiên bản trong một lớp, C# sẽ không cung cấp hàm tạo không tham số.
Khởi tạo dữ liệu lớp bằng cách sử dụng tham số hàm dựng
Các tham số truyền cho hàm tạo là cục bộ cho hàm tạo. Tham số thường được sử dụng để khởi tạo các trường dữ liệu của một lớp.
Đoạn mã sau đây hiển thị một lớp có tên Person với hàm tạo khởi tạo personName và personAge trường:
public class Person
{
public string personName;
public string personAge;
public Person()
{
// Field initialization and constructor logic goes here.
personName = "unknown";
personAge = "unknown";
}
public Person(string name)
{
// Field initialization and constructor logic goes here.
personName = name;
personAge = "unknown";
}
public Person(string name, int age)
{
// Field initialization and constructor logic goes here.
personName = name;
personAge = age.ToString();
}
}
static class Program
{
// the Main method is the entry point of the program.
static void Main()
{
Person person1 = new Person();
Person person2 = new Person("Person Two");
Person person3 = new Person("Person Three", 30);
Console.WriteLine($"Person 1 Name: {person1.personName} Age: {person1.personAge}");
Console.WriteLine($"Person 2 Name: {person2.personName} Age: {person2.personAge}");
Console.WriteLine($"Person 3 Name: {person3.personName} Age: {person3.personAge}");
}
}
Trong ví dụ trên đây, lớp Person được xác định với ba hàm tạo. Hàm dựng đầu tiên khởi tạo các trường personName và personAge để "unknown". Hàm dựng thứ hai khởi tạo trường personName với giá trị được truyền trong tham số name và trường personAge thành "unknown". Hàm dựng thứ ba khởi tạo các trường personName và personAge giá trị truyền qua trong tham name và age tương ứng.
Vì các trường là công cộng, họ có thể được truy cập trực tiếp từ các phương Main công cộng. Khi mã chạy, đầu ra sau đây được tạo ra:
Person 1 Name: unknown Age: unknown
Person 2 Name: Person Two Age: unknown
Person 3 Name: Person Three Age: 30
Định nghĩa nội dung biểu thức
Nếu hàm tạo có thể được thực thi như một câu lệnh đơn, bạn có thể sử dụng định nghĩa nội dung biểu thức để gán tham số cho thành viên lớp khi hàm tạo được thực thi.
Ví dụ: hàm dựng sau đây khởi tạo trường modelName với giá trị được chuyển đến tham model sau:
public class Car
{
public string modelName;
public Car(string model) => modelName = model;
}
Lớp Car có một trường công cộng duy nhất, modelName, thuộc loại string. Trường modelName dùng để lưu trữ tên của mẫu xe.
Lớp Car cũng bao gồm một hàm tạo lấy tham số chuỗi đơn có tên model. Hàm tạo sử dụng định nghĩa nội dung biểu thức (được biểu thị bằng cú pháp =>) để khởi tạo trường modelName với giá trị được chuyển đến tham số model biểu thức. Điều này có nghĩa là khi đối tượng Car được tạo đối tượng mới, trường modelName được đặt thành giá trị được cung cấp làm đối số cho hàm tạo.
Như thuật ngữ của nghĩa nghĩa, phía bên phải của toán tử => là một biểu thức và không bị giới hạn trong một câu lệnh gán đơn giản. Biểu thức có thể là bất kỳ biểu thức C# hợp lệ nào trả về một giá trị.
Đoạn mã sau đây minh họa cách thực thi định nghĩa nội dung biểu thức thực hiện tính toán đơn giản:
public class Employee
{
public int Salary;
public Employee() { }
public Employee(int annualSalary) => Salary = annualSalary;
public Employee(int weeklySalary, int numberOfWeeks) => Salary = weeklySalary * numberOfWeeks;
}
Có thể tạo lớp này bằng cách sử dụng một trong các câu lệnh sau:
Employee e1 = new Employee(30000);
Employee e2 = new Employee(500, 52);
Hàm tạo tĩnh
Hàm tạo tĩnh được sử dụng để khởi tạo bất kỳ dữ liệu tĩnh nào hoặc để thực hiện một hành động cụ thể chỉ cần thực hiện một lần. Nó được gọi tự động trước khi phiên bản đầu tiên được tạo ra hoặc bất kỳ thành viên tĩnh nào được tham chiếu. Hàm tạo tĩnh được gọi nhiều nhất một lần.
Đoạn mã sau đây hiển thị phiên bản cập nhật của lớp Person thực thi các trường tĩnh và hàm tạo tĩnh:
public class Person
{
public string personName;
public string personAge;
// Static field
public static string defaultName;
public static string defaultAge;
// Static constructor
static Person()
{
// Static field initialization
defaultName = "unknown";
defaultAge = "unknown";
}
public Person()
{
// Field initialization and constructor logic goes here.
personName = defaultName;
personAge = defaultAge;
}
public Person(string name)
{
// Field initialization and constructor logic goes here.
personName = name;
personAge = defaultAge;
}
public Person(string name, int age)
{
// Field initialization and constructor logic goes here.
personName = name;
personAge = age.ToString();
}
}
Lớp cập Person cập nhật có hai trường phiên bản, personName và personAge, cả hai đều thuộc kiểu string. Các trường này lưu trữ tên và tuổi của một người tương ứng.
Lớp này cũng xác định hai trường tĩnh, defaultName và defaultAge, cũng thuộc loại string. Các trường tĩnh được chia sẻ giữa tất cả các phiên bản của lớp và chỉ được khởi tạo một lần. Trong trường hợp này, các trường tĩnh được sử dụng để cung cấp giá trị mặc định cho personName và personAge trường.
Hàm tạo tĩnh static Person() chịu trách nhiệm khởi tạo các trường tĩnh. Nó đặt defaultName thành "unknown" và defaultAge thành "unknown". Hàm tạo tĩnh được gọi tự động trước khi tạo bất kỳ phiên bản nào của lớp hoặc bất kỳ thành viên tĩnh nào được truy nhập.
Lớp Person gồm ba hàm tạo thể hiện:
Hàm dựng không tham public Person() khởi tạo các trường personName và personAge với giá trị của các trường tĩnh defaultName và defaultAge. Điều này có nghĩa là nếu không có đối số nào được cung cấp khi tạo đối tượng Person, các giá trị mặc định "unknown" được sử dụng cho cả tên và tuổi.
Hàm public Person(string name) nhận một tham số đơn, name, và khởi tạo trường personName với giá trị này. Trường personAge được khởi tạo với giá trị của trường defaultAge. Hàm tạo này cho phép tạo đối tượng Person với tên đã xác định trong khi sử dụng tuổi mặc định.
Hàm dựng có public Person(string name, int age) hai tham số, name và age. Nó khởi tạo trường personName với giá trị của tham số name và trường personAge với chuỗi đại diện cho tham số tuổi. Hàm tạo này cho phép tạo đối tượng Person với cả đối tượng name và age.
Thuộc tính của hàm dựng tĩnh
Hàm tạo tĩnh có các thuộc tính sau:
Hàm tạo tĩnh không lấy bổ trợ truy nhập hoặc có tham số.
Lớp chỉ có thể có một hàm tạo tĩnh.
Không thể kế thừa hay quá tải hàm tạo tĩnh.
Hàm tạo tĩnh không thể được gọi trực tiếp và chỉ được gọi bằng thời gian chạy ngôn ngữ chung (CLR). Tính năng này được gọi tự động.
Người dùng không có quyền kiểm soát khi hàm tạo tĩnh được thực thi trong chương trình.
Hàm tạo tĩnh được gọi tự động. Nó khởi tạo lớp trước khi trường hợp đầu tiên được tạo ra hoặc bất kỳ thành viên tĩnh tuyên bố trong lớp đó (không phải lớp cơ sở của nó) được tham chiếu. Hàm tạo tĩnh chạy trước trình xây dựng phiên bản. Nếu khởi tạo biến số trường tĩnh có mặt trong lớp của hàm tạo tĩnh, chúng chạy theo thứ tự văn bản trong đó chúng xuất hiện trong khai báo lớp. Khởi tạo chạy ngay lập tức trước hàm tạo tĩnh.
Nếu bạn không cung cấp hàm tạo tĩnh để khởi tạo các trường tĩnh, tất cả các trường tĩnh sẽ được khởi tạo thành giá trị mặc định.
Nếu hàm tạo tĩnh trả về một ngoại lệ, thì thời gian chạy không gọi ra lần thứ hai và kiểu này vẫn chưa được khởi tạo trong suốt vòng đời của miền ứng dụng. Thông thường nhất, một ngoại lệ
TypeInitializationExceptionxuất hiện khi một hàm tạo tĩnh không thể tạo đối tượng loại hoặc cho một ngoại lệ chưa được xử lý xảy ra trong một hàm dựng tĩnh. Đối với các hàm tạo tĩnh không được xác định rõ ràng trong mã nguồn, khắc phục sự cố có thể yêu cầu kiểm tra mã ngôn ngữ trung gian (IL).Sự hiện diện của một hàm tạo tĩnh ngăn việc bổ sung thuộc
BeforeFieldInitloại. Điều này giới hạn tối ưu hóa thời gian chạy.Một trường được khai báo là
static readonlychỉ có thể được gán như một phần của khai báo hoặc trong hàm tạo tĩnh. Khi không bắt buộc phải có hàm dựng tĩnh rõ ràng, hãy khởi tạo các trường tĩnh tại khai báo thay vì khởi tạo tĩnh để tối ưu hóa thời gian chạy tốt hơn.Thời gian chạy gọi bộ cấu trúc tĩnh không quá một lần trong một miền ứng dụng đơn. Cuộc gọi đó được thực hiện trong vùng bị khóa dựa trên loại lớp cụ thể. Không cần cơ chế khóa bổ sung trong nội dung của một hàm tạo tĩnh.
Ghi
Mặc dù không thể truy nhập trực tiếp, sự hiện diện của một hàm dựng tĩnh rõ ràng nên được ghi lại để hỗ trợ khắc phục sự cố ngoại lệ khởi tạo.