Passing by value
Our copier has one more quirk. It never touches your sheets: before it starts, it makes an exact copy of them and works on the copy. Whatever it does to the copy, your sheets stay untouched on the glass.
A method in C# behaves the same way. Let's see what happens when a method changes its parameter:
int x = 5;
AddTen(x); // 15
Console.WriteLine(x); // 5
void AddTen(int n)
{
n = n + 10;
Console.WriteLine(n);
}A copy on every call
Let's walk through the example line by line:
int x = 5;creates the variablex.- On the call
AddTen(x), C# copies the value ofxinto the parametern: nownis5. n = n + 10changes the copy:nbecomes15, and the method prints15.- The method ends, and
nis gone.Console.WriteLine(x)prints5: nobody touched the variablex.
A method gets a copy of the argument's value, not the variable itself. This is called passing by value, and it is what C# does by default.
For the types int, double, bool and char, the copy is fully independent of the original. These are value types: their variable holds the value itself, and that value is what a call copies.
Interviewers often ask this: "How does C# pass arguments to a method?" The answer has two parts:
- by value by default: the method gets a copy, and assigning to the parameter does not change the caller's variable;
- passing the variable itself is possible too, but you have to say so explicitly in both the method's declaration and the call.
A parameter is a separate variable
A parameter is an ordinary variable of the method:
- you can read and change it like any other;
- it is created on every call and disappears when the method ends;
- it has no link to the caller's variable.
There are two cases where a link only seems to exist.
An expression as the argument
An argument can be an expression, not only a variable. On the call AddTen(x + 1), C# first computes 6 and copies that number into n. The method sees only the number and does not know where it came from.
The same name
The same name does not link anything either. If you name the parameter x, like the variable outside, there are still two variables. Inside the method the name x means the parameter, and assigning to it leaves the outer x alone.
Returning a new value
The methods in this lesson are linked to the calling code by two paths:
- the arguments going in;
- the result coming out.
For the calling code to get a new value, the method returns it with return. The calling code decides what to do with the result:
int x = 5;
Console.WriteLine(PlusTen(x)); // 15
Console.WriteLine(x); // 5
x = PlusTen(x);
Console.WriteLine(x); // 15
int PlusTen(int n)
{
return n + 10;
}Let's go through the lines after int x = 5;:
PlusTen(x)returns15, andConsole.WriteLineprints that number.- The next line prints
5: the method returned a new value but did not changex. x = PlusTen(x)stores the result of the second call back inx.- The last line prints
15: the variable changed only after the assignment.
The copier handed out the finished sheet, and you filed it in your own folder.
This is where the picture ends. A real copier needs paper and time for every copy, while C# copies the argument's value on every call, and for a number that takes no time at all.
Common mistake
The method returns a new value, but the result of the call was not stored anywhere:
int x = 5;
PlusTen(x); // ✗
Console.WriteLine(x); // 5The program compiles and prints 5. A method call can stand as a statement of its own even when the method returns a value, and then the result is lost. The compiler gives no warning about it, so store the result explicitly: x = PlusTen(x);.
Key points
- A method gets a copy of the argument's value: assigning to the parameter does not change the caller's variable.
- In C#, arguments are passed by value by default.
- A method returns a new value with
return, and the calling code stores it in a variable itself:x = PlusTen(x);.