A method can have a sequence of parameters.
Parameters define the set of arguments that must be provided for that method.
In the following example, the method myMethod
has
a single parameter named p
, of type int
:
static void myMethod (int p) {
p = p + 1; // Increment p by 1
Console.WriteLine(p); // Write p to screen
}
static void Main() {
myMethod (8);
}
We can control how parameters are passed with the ref
and out
modifiers.
The following table lists the features of ref
and out
modifiers.
Modifier | Item | Variable must be definitely assigned |
---|---|---|
(None) | Value | Going in |
ref | Reference | Going in |
out | Reference | Going out |
By default, arguments in C# are passed by value. Passing by value means a copy of the value is created when passed to the method:
class Main { /*w w w . ja va 2 s . com*/
static void myMethod (int p) {
p = p + 1; // Increment p by 1
Console.WriteLine (p); // Write p to screen
}
static void Main() {
int x = 8;
myMethod (x); // Make a copy of x
Console.WriteLine (x); // x will still be 8
}
}
Assigning p
a new value does not change the
contents of x
.
Passing a reference-type argument by value copies the reference, not the object.
In the following example, myMethod
sees the
same StringBuilder
object that Main
instantiated,
but has an independent reference to it.
sb
and myMethodSB
are two different
variables that reference the same StringBuilder
object:
class Main { // w ww . j av a 2 s . c o m
static void myMethod (StringBuilder myMethodSB) {
myMethodSB.Append ("test");
myMethodSB = null;
}
static void Main() {
StringBuilder sb = new StringBuilder();
myMethod (sb);
Console.WriteLine (sb.ToString()); // test
}
}
myMethodSB
is a copy of a reference, setting it to null
doesn't make sb null.
To pass by reference, C# provides the ref
parameter modifier.
In the following
example, p
and x
refer to the same memory locations:
class Test { //from ww w. j a v a2s. co m
static void myMethod (ref int p) {
p = p + 1; // Increment p by 1
Console.WriteLine (p); // Write p to screen
}
static void Main(){
int x = 8;
myMethod (ref x); // Ask myMethod to deal directly with x
Console.WriteLine (x); // x is now 9
}
}
Assigning p
a new value changes the x
.
ref
modifier is required both when writing and when calling the method.
The following code shows how to use ref
modifier to create a swap method:
class Test {/* w ww. j av a2s . c o m*/
static void Swap (ref string a, ref string b){
string temp = a;
a = b;
b = temp;
}
static void Main() {
string x = "A";
string y = "B";
Swap (ref x, ref y);
Console.WriteLine (x);
Console.WriteLine (y);
}
}
A parameter can be passed by reference or by value, regardless of whether the parameter type is a reference type or a value type.
An out argument is like a ref
argument, except it:
The out
modifier is used to get multiple return values from a
method.
For example:
class Test { /* w ww . ja v a 2 s . c o m*/
static void ToWords (string name, out string firstNames, out string lastName) {
int i = name.LastIndexOf (' ');
firstNames = name.Substring (0, i);
lastName = name.Substring (i + 1);
}
static void Main(){
string a, b;
ToWords("this is a test", out a, out b);
Console.WriteLine (a);
Console.WriteLine (b);
}
}
Like a ref
parameter, an out
parameter is passed by reference.
The params
parameter modifier is used on the last parameter of a method
so that the method accepts any number of parameters of a particular type.
The parameter type must be declared as an array.
For example:
class Test { /*from ww w .j a v a 2s .co m*/
static int Sum (params int[] ints) {
int sum = 0;
for (int i = 0; i < ints.Length; i++) {
sum += ints[i]; // Increase sum by ints[i]
}
return sum;
}
static void Main(){
int total = Sum (1, 2, 3, 4);
Console.WriteLine (total); // 10
}
}
We can also supply a params
argument as an ordinary array.
int total = Sum (new int[] { 1, 2, 3, 4 } );
C# methods, constructors, and indexers can declare optional parameters.
A parameter is optional if it specifies a default value in its declaration:
void myMethod (int x = 23) {
Console.WriteLine (x);
}
Optional parameters may be omitted when calling the method:
myMethod(); // 23
The default argument of 23 is actually passed to the optional parameter x
.
The preceding call to myMethod is semantically identical to:
myMethod (23);
Optional parameters cannot be marked with ref
or out
.
The default value of an optional parameter must be a constant expression, or a parameter less constructor of a value type.
Mandatory parameters must occur before optional parameters in both the method declaration and the method call.
In the following example, the explicit value of 1 is passed to x
,
and the default value of 0 is passed to y
:
void myMethod (int x = 0, int y = 0) {
Console.WriteLine (x + ", " + y);
}
void Test() {
myMethod(1); // 1, 0
}
To pass a default value to x
and an explicit value to y
we must
combine optional parameters with named arguments.
We can identify an argument by name. For example:
void myMethod (int x, int y) {
Console.WriteLine (x + ", " + y);
}
void Test() {
myMethod (x:1, y:2); // 1, 2
}
Named arguments can occur in any order.
The following calls to myMethod are semantically identical:
myMethod (x:1, y:2);
myMethod (y:2, x:1);
We can mix named and positional parameters:
myMethod (1, y:2);
Positional parameters must come before named arguments.
So we couldn't call myMethod
like this:
myMethod (x:1, 2); // Compile-time error
Named arguments are useful with optional parameters.
For instance, consider the following method:
void myMethod (int a = 0, int b = 0, int c = 0, int d = 0) { ... }
We can call this supplying only a value for d
as follows:
myMethod (d:3);