CSharp/C# Tutorial - C# Parameters






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.

ModifierItemVariable must be definitely assigned
(None)ValueGoing in
refReferenceGoing in
outReferenceGoing out




Passing arguments by value

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.





The ref modifier

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.

The out modifier

An out argument is like a ref argument, except it:

  • Need not be assigned before going into the function
  • Must be assigned before it comes out of the function

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 modifier

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 } ); 

Optional parameters

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.

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);