Trong C#, cả lớp (class) và cấu trúc (struct) đều được sử dụng để định nghĩa các kiểu dữ liệu tùy chỉnh, nhưng chúng có những khác biệt quan trọng về cách chúng hoạt động và cách chúng được sử dụng.
1. Kiểu Tham Chiếu vs. Kiểu Giá Trị
- Class: Là kiểu tham chiếu (reference type). Điều này có nghĩa là khi bạn tạo một đối tượng của lớp và gán nó cho một biến, biến này sẽ lưu trữ một tham chiếu (địa chỉ bộ nhớ) tới đối tượng chứ không phải chính đối tượng.
- Struct: Là kiểu giá trị (value type). Điều này có nghĩa là khi bạn tạo một đối tượng của cấu trúc và gán nó cho một biến, biến này sẽ lưu trữ bản sao của đối tượng đó.
2. Bộ Nhớ và Hiệu Suất
- Class: Đối tượng của lớp được lưu trữ trên heap, và biến tham chiếu tới chúng được lưu trữ trên stack. Việc cấp phát và thu hồi bộ nhớ trên heap chậm hơn so với stack.
- Struct: Đối tượng của cấu trúc được lưu trữ trực tiếp trên stack (trừ khi chúng là một phần của một đối tượng khác trên heap). Việc lưu trữ trên stack thường nhanh hơn và thu hồi bộ nhớ ngay lập tức khi biến ra khỏi phạm vi.
3. Sử Dụng Khi Nào?
- Class: Thường được sử dụng khi bạn cần tạo các đối tượng có thể thay đổi (mutable), hoặc khi bạn cần sử dụng tính năng kế thừa (inheritance) và đa hình (polymorphism).
- Struct: Thường được sử dụng cho các đối tượng nhỏ, không thay đổi (immutable) và không cần tính năng kế thừa. Ví dụ, các loại dữ liệu đơn giản như
Point
,Rectangle
, hoặc các loại dữ liệu số học phức tạp.
4. Kế Thừa
- Class: Hỗ trợ kế thừa. Một lớp có thể kế thừa từ một lớp cơ sở khác và có thể được kế thừa bởi các lớp con.
- Struct: Không hỗ trợ kế thừa. Cấu trúc không thể kế thừa từ cấu trúc khác hoặc từ lớp khác. Tuy nhiên, cấu trúc có thể thực hiện các giao diện (interface).
5. Tạo Đối Tượng
- Class: Đối tượng của lớp có thể được tạo bằng từ khóa
new
.MyClass obj = new MyClass();
- Struct: Đối tượng của cấu trúc có thể được tạo mà không cần từ khóa
new
, nhưng sử dụngnew
giúp đảm bảo tất cả các trường được khởi tạo.MyStruct obj = new MyStruct(); // Tất cả các trường được khởi tạo MyStruct obj2; // Các trường không được khởi tạo
6. Biến Thành Viên
- Class: Các biến thành viên của lớp có thể được khởi tạo với giá trị mặc định (default values) hoặc với các giá trị tùy chỉnh.
- Struct: Các biến thành viên của cấu trúc không thể được khởi tạo trực tiếp bên trong cấu trúc. Tất cả các biến thành viên phải được khởi tạo trong constructor hoặc phải có giá trị mặc định.
Ví Dụ
Class
public class MyClass
{
public int X { get; set; }
public int Y { get; set; }
public MyClass(int x, int y)
{
X = x;
Y = y;
}
}
Struct
public struct MyStruct
{
public int X { get; set; }
public int Y { get; set; }
public MyStruct(int x, int y)
{
X = x;
Y = y;
}
}
Tổng Kết
- Class: Sử dụng khi bạn cần một kiểu tham chiếu, hỗ trợ kế thừa, và có thể chứa các đối tượng lớn, phức tạp.
- Struct: Sử dụng khi bạn cần một kiểu giá trị, không cần kế thừa, và đối tượng nhỏ, đơn giản.
Việc lựa chọn giữa lớp và cấu trúc phụ thuộc vào yêu cầu cụ thể của ứng dụng và cách bạn muốn quản lý bộ nhớ và hiệu suất.
Comments