ECMA-334 C# Language Specification

14.4.1: Argument lists

Every function member invocation includes an argument list, which provides actual values or variable references for the parameters of the function member. The syntax for specifying the argument list of a function member invocation depends on the function member category:

The arguments of properties (17.6), events (17.7), indexers (17.8), and user-defined operators (17.9) are always passed as value parameters (17.5.1.1). Reference and output parameters are not supported for these categories of function members.

The arguments of an instance constructor, method, or delegate invocation are specified as an argument-list:

argument-list
argument
argument-list , argument
expression
ref variable-reference
out variable-reference

An argument-list consists of one or more arguments, separated by commas. Each argument can take one of the following forms:

During the run-time processing of a function member invocation (14.4.3), the expressions or variable references of an argument list are evaluated in order, from left to right, as follows:

Methods, indexers, and instance constructors may declare their right-most parameter to be a parameter array (17.5.1.4). Such function members are invoked either in their normal form or in their expanded form depending on which is applicable (14.4.2.1):

The expressions of an argument list are always evaluated in the order they are written. [Example: Thus, the example
class Test  
{  
   static void F(int x, int y, int z) {  
      System.Console.WriteLine("x = {0}, y = {1}, z = {2}", x, y, z);  
   }  
   static void Main() {  
      int i = 0;  
      F(i++, i++, i++);  
   }  
}  
produces the output
x = 0, y = 1, z = 2  
end example]

The array covariance rules (19.5) permit a value of an array type A[] to be a reference to an instance of an array type B[], provided an implicit reference conversion exists from B to A. Because of these rules, when an array element of a reference-type is passed as a reference or output parameter, a run-time check is required to ensure that the actual element type of the array is identical to that of the parameter. [Example: In the example
class Test  
{  
   static void F(ref object x) {...}  
   static void Main() {  
      object[] a = new object[10];  
      object[] b = new string[10];  
      F(ref a[0]);    // Ok  
      F(ref b[1]);   // ArrayTypeMismatchException  
   }  
}  
the second invocation of F causes a System.ArrayTypeMismatchException to be thrown because the actual element type of b is string and not object. end example]

When a function member with a parameter array is invoked in its expanded form, the invocation is processed exactly as if an array creation expression with an array initializer (14.5.10.2) was inserted around the expanded parameters. [Example: For example, given the declaration
void F(int x, int y, params object[] args);  
the following invocations of the expanded form of the method
F(10, 20);  
F(10, 20, 30, 40);  
F(10, 20, 1, "hello", 3.0);  
correspond exactly to
F(10, 20, new object[] {});  
F(10, 20, new object[] {30, 40});  
F(10, 20, new object[] {1, "hello", 3.0});  
end example]
In particular, note that an empty array is created when there are zero arguments given for the parameter array.