Cả ba đều truyền tham số theo tham chiếu (không copy), khác ở hướng dữ liệu và ràng buộc khởi tạo:
| Modifier | Init trước khi gọi? | Method phải gán? | Đọc/Ghi trong method |
|---|---|---|---|
ref | Bắt buộc | Không | Đọc và ghi |
out | Không cần | Bắt buộc | Chỉ để xuất ra |
in | Bắt buộc | Không (chỉ đọc) | Chỉ đọc |
csharp
void Swap(ref int a, ref int b) { (a, b) = (b, a); }
bool TryParse(string s, out int value) { value = 0; /* ... */ return true; }
double Length(in Vector3 v) => Math.Sqrt(v.X*v.X + v.Y*v.Y + v.Z*v.Z); // v không sửa đượcref: cần truyền vào rồi lấy ra giá trị đã đổi (vd hoán đổi).out: chỉ để trả nhiều giá trị ra ngoài — kinh điển là mẫuTry...(int.TryParse).in: truyền tham chiếu read-only, tối ưu khi tham số là struct lớn mà không muốn copy và không cho method sửa.