To ref or not to ref
So the question is what is the point of passing a reference type along with the ref keyword?
Scenario 1:
I have an Employee class as below.
1: public class Employee
2: {
3: public string FirstName { get; set; }
4: public string LastName { get; set; }
5:
6: public override string ToString()
7: {
8: return string.Format("{0}-{1}", FirstName, LastName);
9: }
10: }
In my calling class, I say:
1: class Program
2: {
3: static void Main()
4: {
5: Employee employee = new Employee
6: {
7: FirstName = "John",
8: LastName = "Doe"
9: };
10: Console.WriteLine(employee);
11: CallSomeMethod(employee);
12: Console.WriteLine(employee);
13: }
14:
15: private static void CallSomeMethod(Employee employee)
16: {
17: employee.FirstName = "Smith";
18: employee.LastName = "Doe";
19: }
20: }
After having a look at the code, you’ll probably say,
Well, an instance of a class gets passed as a reference, so any changes to the instance inside the CallSomeMethod, actually modifies the original object. Hence the output will be ‘John-Doe’ on the first call and ‘Smith-Doe’ on the second.
And you’re right:
So the question is what’s the use of passing this Employee parameter as a ref?
Scenario 2:
1: class Program
2: {
3: static void Main()
4: {
5: Employee employee = new Employee
6: {
7: FirstName = "John",
8: LastName = "Doe"
9: };
10: Console.WriteLine(employee);
11: CallSomeMethod(ref employee);
12: Console.WriteLine(employee);
13: }
14:
15: private static void CallSomeMethod(ref Employee employee)
16: {
17: employee.FirstName = "Smith";
18: employee.LastName = "Doe";
19: }
20: }
The output is still the same:
Ok, so is there really a need to pass a reference type using the ref keyword? I’ll remove the ‘ref’ keyword and make one more change to the CallSomeMethod method.
Scenario 3:
1: class Program
2: {
3: static void Main()
4: {
5: Employee employee = new Employee
6: {
7: FirstName = "John",
8: LastName = "Doe"
9: };
10: Console.WriteLine(employee);
11: CallSomeMethod(employee);
12: Console.WriteLine(employee);
13: }
14:
15: private static void CallSomeMethod(Employee employee)
16: {
17: employee = new Employee
18: {
19: FirstName = "Smith",
20: LastName = "John"
21: };
22: }
23: }
In line 17 you’ll see I’ve ‘new’d up the incoming Employee parameter and then set its properties to new values. The output tells me that the original instance of the Employee class does not change.
Huh? But an instance of a class gets passed by reference, so why did the values not change on the original instance or how do I keep the two instances in-sync all the times?
Aah, now here’s the answer. In order to keep the objects in sync, you pass them using the ‘ref’ keyword.
Scenario 5:
1: class Program
2: {
3: static void Main()
4: {
5: Employee employee = new Employee
6: {
7: FirstName = "John",
8: LastName = "Doe"
9: };
10: Console.WriteLine(employee);
11: CallSomeMethod(ref employee);
12: Console.WriteLine(employee);
13: }
14:
15: private static void CallSomeMethod(ref Employee employee)
16: {
17: employee = new Employee
18: {
19: FirstName = "Smith",
20: LastName = "John"
21: };
22: }
23: }
Viola!
Verdict: ref key came to the rescue and saved the planet… again!
PS: Sorry for the confusion earlier folks. I hope I've fixed it this time.