LA.NET [EN]

Sep 01

Parameters: by value or by reference? Say what?

Posted in Basics C#      Comments Off on Parameters: by value or by reference? Say what?

I’m guessing that I won’t be giving any news when I say that parameters are used for passing values into methods. By default, parameters are passed by value. Here’s a quick example which will let us discuss this behavior:

public class Student {
    public String Name { get; set; }
    public Int32 Age { get; set; }
}
static void ChangeName(Student std) {
    std.Name = DateTime.Now.ToString()
}

As I was saying, parameters are passed by value. And that’s true. However, many still are surprised when they discover that ChangeName will update the Name of the Student’s instance that was passed into the method. How can that be? Isn’t passing by value the same as “copying”? Well, that is absolutely correct. What you must keep in mind is the *type* of variable you’re passing into  the method.

In my previous instance, Student is a reference type. What that means is that a variable of that type will reference some memory space, which is where the values of its fields will be stored. Now, even though I don’t like to talk about implementation details, I’d say that they help (at least, in this case). Lets suppose we’ve got some variable std:

var std = new Student { Name = "Luis", Age = 34 };

Now, you can think of std as holding the memory address where the Student object was allocated. When you look at if from this perspective,things might start to make sense,right? Suppose you’ve got the following code:

ChangeName(std);

Since ChangeName’s only parameter is passed by value, you should be able to see what’s going on. The value of the std variable is copied to th the std parameter and that means that the std will hold a memory address. When the ChangeName starts  executing, there are two “variables” pointing at the same “memory location”: the parameter and the variable which was passed into the method through that parameter. That’s why if you try to change the  value of the std parameter (ie, make it reference another instance of Student), that change won’t be replicated outside the method (notice that changing the value isn’t the same as changing the property of object to which the parameter “points” to). Here’s a quick example of what I mean:

static void ChangeName(Student std) {
    std = new Student { Name = "John", Age = 40 };
}

var std = new Student { Name = "Luis", Age = 34 };
ChangeName(std);
Console.WriteLine(std.Name);//prints Luis, not John

See the difference? If the std parameter was passed by reference, then the std variable would point to the new Student instance allocated inside the method. If you run the previous code, you’ll see that that doesn’t happen.

How, then, can we change this behavior? Simply by indicating that the parameters should be passed by reference. We’ll see how in the next post, so stay tuned!