Now that we've covered the basics of parameters and return values, we need to cover some important details about how information flows between methods.
Consider the following program:
using System; class ChangeFormal { static void Main() { int num = 0; ChangeIt(num); Console.WriteLine(num); } static void ChangeIt(int something) { something = 25; } }
Take a close look at the ChangeIt() method. The value of the formal parameter something is changed to 25. The question for consideration is this: does the assignment to the formal parameter "ripple back" to affect the actual parameter, num?
The answer is: No. The actual parameter and the formal parameter are two different variables, and assignments to the formal do not affect the actual.
The only connection between an actual parameter and a formal occurs at the beginning of a method call, when the value of the actual parameter is copied into the corresponding formal parameter. After the formal parameter receives its value from the actual parameter, any changes to the formal will not affect the actual. Think of it is as "one way" connection: actuals supply input for formals, but changes to formals do not "output" back to actuals.
So, what do you do if you would like a method to be able to affect the actual variable passed to it? You need to use a reference parameter.
Take a look at a slightly modified version of the program listing in the previous section:
using System; class ChangeFormal { static void Main() { int num = 0; ChangeIt(ref num); Console.WriteLine(num); } static void ChangeIt(ref int something) { something = 25; } }
Note the use of the keyword ref -- both in the call to ChangeIt, and in the formal parameter definition inside the definition of ChangeIt. This causes the computer to establish a "link" between the formal parameter something and the actual parameter num. When the ChangeIt method changes something to 25, the change now ripples back and updates the actual parameter num.
When you mark a formal parameter with the keyword ref, you indicate that it is a reference parameter, instead of the normal kind of formal parameter (called value parameters). Assignments to reference parameters affect the corresponding actuals, which must be marked with the keyword ref in the call to the method.
Reference parameters give you another way to return information from a method to its caller. For example, here is a method that computes determines the smaller and larger of two numbers:
// computes the larger of <num1> and <num2> and returns via <result> static void MinMax(int num1, int num2, ref int smaller, ref int larger) { if (num1 > num2) { larger = num1; smaller = num2; } else { larger = num2; smaller = num1; } }
You might call this method in a program like this:
int big = 0, little = 0; MinMax(3, 5, ref little, ref big); // little set to 3, big set to 5
This method returns two values: the smaller and larger of the first two parameters. It is not a particularly good example, because methods should usually designed to do one logical thing, and this one does two very different things. But it serves to illustrate how you can return multiple values from one method.
Now you know two techniques to return information: using return statements, and using reference parameters. Usually, you should return values using return statements. Use reference parameters only when you really need to return multiple values from a method.