Đây là một câu hỏi mình hay nhận được khi đi phỏng vấn vị trí lập trình .NET Developer, một câu hỏi khá cơ bản nhưng hàm chứa rất nhiều kiến thức cần phải có, phải hiểu. Đi sâu vào nhé:
Value là gì ?
Giá trị là nội dung thực tế mà một biến đại diện. Ví dụ:
int number = 10;
Với khai báo trên, ta hiểu rằng biến có tên "number", kiểu dữ liệu là integer và có giá trị là 10.
Pass by value (Truyền tham trị)
Tham trị là cách thức truyền giá trị của biến vào hàm khi hàm được gọi. Trong phương pháp này, một bản sao của giá trị được truyền cho hàm. Mọi thay đổi đối với tham số trong hàm không ảnh hưởng đến biến ban đầu. Ví dụ:
using System; public class Program
{ public static void ModifyValue(int x) { x = 10; } public static void Main() { int a = 5; ModifyValue(a); Console.WriteLine(a); // a vẫn là 5 }
}
Trong ví dụ này, giá trị của a vẫn là 5 sau khi gọi hàm ModifyValue, vì x là một bản sao của a.
Reference (Tham chiếu)
Tham chiếu (Reference): Trong ngữ cảnh lập trình, tham chiếu là một cách tiếp cận để truy cập giá trị của một biến thông qua một tên khác, hay nói cách khác, tham chiếu là một alias (bí danh) cho biến khác.
int a = 5; Console.WriteLine($"Trước khi gọi hàm: a = {a}"); ModifyValue(ref a); Console.WriteLine($"Sau khi gọi hàm: a = {a}"); }
}
Phương thức ModifyValue nhận một tham số kiểu int với từ khóa ref. Điều này có nghĩa là x là một tham chiếu đến biến được truyền vào, cho phép phương thức này thay đổi giá trị của biến gốc.
Ngoài ra, ta có thể dùng từ khóa out, với kết quả tương tự, nhưng với out thì yêu cầu phải gán giá trị bên trong hàm trước khi trả về
int a; ModifyValue(out a); Console.WriteLine($"Sau khi gọi hàm: a = {a}"); }
}
Pass by Reference (Truyền tham chiếu)
Đây là phương pháp truyền tham số vào hàm bằng cách truyền địa chỉ hoặc tham chiếu đến biến thực sự. Điều này có nghĩa là mọi thay đổi đối với tham số trong hàm sẽ ảnh hưởng trực tiếp đến biến gốc.
using System; public class Program
{ public static void ModifyValue(ref int x) { x = 10; } public static void Main() { int a = 5; ModifyValue(ref a); Console.WriteLine(a); // a bây giờ là 10 }
}
Hoặc
using System; public class Program
{ public static void ModifyValue(out int x) { x = 10; } public static void Main() { int a; ModifyValue(out a); Console.WriteLine(a); // a bây giờ là 10 }
}
Tóm tắt
Giá trị là nội dung mà biến đại diện
Tham chiếu là một alias cho một biến khác, cho phép truy cập và thay đổi giá trị của biến đó.
Truyền tham trị (pass by value): Truyền một bản sao của giá trị biến. Thay đổi tham số trong hàm không ảnh hưởng đến biến gốc.
Truyền tham chiếu (pass by reference): Truyền tham chiếu đến biến gốc bằng từ khóa ref hoặc out. Thay đổi tham số trong hàm sẽ ảnh hưởng trực tiếp đến biến gốc.
Câu hỏi tình huống
Câu 1
Khai báo như sau:
int a= 10; object o = .... Vậy trong 2 cái trên, cái nào là tham chiếu, cái nào là giá trị biến?
Đáp:
Trong khi báo trên, biến a là biến giữ giá trị, còn biến o là biến giữ tham chiếu
Câu 2
Tiếp tục như trên
var b = o; Biến b lúc này là giá trị hay tham chiếu?
Đáp:
Vì kiểu dữ liệu là "var" nên b lúc này sẽ tham chiếu đến o
Câu 3
var b = o; b.Name = "Changed" Vậy property "Name" ở biến o có bị thay đổi ko ?
Đáp:
Vì là tham chiếu nên b và a lúc này chứa cùng 1 object, giá trị thay đổi!
Trên là tóm tắt một tình huống hỏi và đi sâu về value và ref / out trong C#, hy vọng các bạn có những đúc kết riêng cho mình.