Value type và reference type
Nội dung bài · 5 mục
- 1.Khái niệm
- 2.Ví dụ
- 3.Thử ngay
- 4.Lỗi hay gặp
- 5.Tóm tắt
Bạn chép giỏ hàng mẫu cho khách A, rồi thêm món vào giỏ của A. Mở giỏ mẫu ra, món đó cũng có mặt. Không có dòng nào gán nhầm. Lý do: C# sao chép value type và reference type theo hai cách khác nhau.
Khái niệm
📑 Value type: kiểu mà biến chứa trực tiếp giá trị, gán sang biến khác là chép cả giá trị.
🔗 Reference type: kiểu mà biến chỉ chứa tham chiếu tới object, gán sang biến khác là chép tham chiếu, và hai biến cùng trỏ tới một object.
| Loại | Gồm những kiểu |
|---|---|
| Value type | int, double, decimal, bool |
| Reference type | mọi class, string, array, List, Dictionary |
Ví dụ
int a = 5;
int b = a;
b = 10;
Console.WriteLine(a); // 5
var p1 = new Product { Price = 5000m };
var p2 = p1;
p2.Price = 9000m;
Console.WriteLine(p1.Price); // 9000
class Product
{
public decimal Price { get; set; }
}int b = achép số 5 sangb. Đổibkhông đụng tớia.var p2 = p1chỉ chép tham chiếu.p1vàp2cùng trỏ một object, sửa qua biến nào thì biến kia cũng thấy.new Product { Price = 5000m }tạo object rồi gán luôn property trong cặp{ }.stringlà reference type nhưng không sửa được nội dung, nên dùng giống value type mà không gặp vấn đề này.
Thử ngay
Chép class Product ở ví dụ trên, thay các dòng đầu bằng:
int price = 5000;
var pen = new Product { Price = 5000m };
DiscountNumber(price);
DiscountProduct(pen);
Console.WriteLine(price);
Console.WriteLine(pen.Price);
void DiscountNumber(int value)
{
value = value - 1000;
}
void DiscountProduct(Product product)
{
product.Price = product.Price - 1000m;
}Đoán trước khi chạy: hai method làm cùng một việc. Cả hai giá trị in ra có cùng bị giảm không?
Xem kết quả
5000
4000Không. Tham số int nhận bản chép của số, nên price bên ngoài giữ nguyên.
Tham số Product nhận bản chép của tham chiếu, bản chép này vẫn trỏ tới
object pen, nên sửa bên trong method thì pen đổi theo.
Lỗi hay gặp
Tưởng gán là tạo bản sao. Hai giỏ hàng thành một.
// SAI — cartA và sample là cùng một list
var sample = new List<string> { "Bút bi" };
var cartA = sample;
cartA.Add("Vở");
Console.WriteLine(sample.Count); // 2// ĐÚNG — tạo list mới, chép phần tử sang
var sample = new List<string> { "Bút bi" };
var cartA = new List<string>(sample);
cartA.Add("Vở");
Console.WriteLine(sample.Count); // 1So sánh hai object bằng ==. Với class, == so tham chiếu chứ không so
dữ liệu.
// SAI — in False dù hai sản phẩm giống hệt nhau
var x = new Product { Price = 5000m };
var y = new Product { Price = 5000m };
Console.WriteLine(x == y);// ĐÚNG — so sánh chính dữ liệu cần kiểm tra
var x = new Product { Price = 5000m };
var y = new Product { Price = 5000m };
Console.WriteLine(x.Price == y.Price);Tóm tắt
- Value type chép giá trị, reference type chép tham chiếu.
- Hai biến cùng trỏ một object thì sửa qua biến này, biến kia thấy ngay.
- Truyền object vào method thì method sửa được chính object đó.
- Muốn bản sao độc lập thì phải tạo object mới.
==giữa hai object class so tham chiếu, không so dữ liệu.
Tự kiểm tra
0/3 câuvar a = new List<int> { 1 }; var b = a; b.Add(2); Console.WriteLine(a.Count); In ra gì?
int x = 7; int y = x; x = 0; Console.WriteLine(y); In ra gì?
Kiểu nào là value type?