The ref
-keyword and the out
-keyword change the behavior of C# method parameters. Sometimes we want the actual value of a variable to be copied as the parameter.
Other times we want a reference. These modifiers affect definite assignment analysis. In C# it is also possible to use named and optional parameters, but this only affects syntax.
This program introduces three methods. Example1
uses the default parameter passing technique. Example2
uses the ref
-modifier. And Example3
employs the out
-modifier.
int
value to each of these three methods and examine the results.Example1
uses value-passing semantics. If it assigns the parameter, it only affects the local state of the method.Example2
uses ref
. When this method sets its parameter to 2, this is reflected in the calling location (Main
).Example3
uses the out
-modifier. It sets its parameter to 3—this is reflected in the calling location.using System; class Program { static void Main() { int val = 0; Example1(val); Console.WriteLine(val); // Still 0. Example2(ref val); Console.WriteLine(val); // Now 2. Example3(out val); Console.WriteLine(val); // Now 3. } static void Example1(int value) { value = 1; } static void Example2(ref int value) { value = 2; } static void Example3(out int value) { value = 3; } }0 2 3
Arguments are values that are passed to a specific method call. You can call a method with many different arguments, as many times as you wish.
using System; class Program { static void Main() { // Argument = 5 // Argument = Sam Perls(5, "Sam"); } static void Perls(int id, string name) { Console.WriteLine(id); Console.WriteLine(name); } }5 Sam
Formal parameters are found in the method itself. The names they use are not affected by the argument names.
using System; class Program { static void Main() { Perls(5, "Sam"); } static void Perls(int id, string name) { // Parameter = id // Parameter = name Console.WriteLine(id); Console.WriteLine(name); } }5 Sam
We use the syntax "name:" and then a string
literal to specify the value of the name parameter. The syntax "size:" and then an integer signifies the size parameter.
using System; class Program { static void Main() { // Call the Test method several times in different ways. Test(name: "Perl", size: 5); Test(name: "Dot", size: -1); Test(6, "Net"); Test(7, name: "Cat"); } static void Test(int size, string name) { Console.WriteLine("Size = {0}, Name = {1}", size, name); } }Size = 5, Name = Perl Size = -1, Name = Dot Size = 6, Name = Net Size = 7, Name = Cat
We introduce a method named "Method" that has 2 parameters. Each of the parameters is optional. We use special syntax form to declare them.
Method()
with no parameters. And we can call it with only an int
parameter.using System; class Program { static void Main() { // Omit the optional parameters. Method(); // Omit second optional parameter. Method(4); // You can't omit the first but keep the second. // Method("Dot"); // Classic calling syntax. Method(4, "Dot"); // Specify one named parameter. Method(name: "Tara"); // Specify both named parameters. Method(value: 5, name: "Tara"); } static void Method(int value = 1, string name = "Perl") { Console.WriteLine("value = {0}, name = {1}", value, name); } }value = 1, name = Perl value = 4, name = Perl value = 4, name = Dot value = 1, name = Tara value = 5, name = Tara
What is the difference between the ref
-keyword and the out
-keyword? The difference is in the compiler's definite assignment analysis step.
out
-parameter be "definitely assigned" before any exit. There is no such restriction with ref
.out
-modifier, you can be sure that after you invoke it, your variable is definitely assigned.Unlike the ref
-keyword, the out
-keyword allows us to skip assigning the variable beforehand. With named and optional parameters, we can specify parameters in a more readable way.