Optional Parameters in C# < 4

C# 4.0 adds support for optional parameters.

The following code prints 4:

static void Main() {
    TestMethod();
}
static void TestMethod(int i = 4) {
    Console.WriteLine(i);
}

Optional parameters are a compiler feature.  The compiler will emit a normal method with the IL [opt] attribute and a .param declaration that includes a default value:

.method hidebysig static void 
        TestMethod([opt] int32 i) cil managed
{
    .param [1] = int32(4)
    .maxstack 8
    L_0001: ldarg.0 
    L_0002: call void [mscorlib]System.Console::WriteLine(int32)
    L_0007: ret 
}

Earlier versions of the C# compiler will ignore this metadata.  Therefore, you can call such methods in earlier versions of C#, but you will always need to pass the optional parameters.

You can also create methods with optional parameters in earlier versions of C#.  You can force the compiler to emit this metadata using the [Optional] and [DefaultParameterValue] attributes.
(in the System.Runtime.InteropServices namespace)

The following C# 1 code will compile identically to the above:

static void TestMethod(
    [Optional, DefaultParameterValue(4)] int i
) {
    Console.WriteLine(i);
}

Since the older compilers cannot consume optional parameters, you will always need to pass i when calling this method from C# < 4.  However, in C# 4, you can call this method without passing the parameter.

Unfortunately, the syntax parser used by VS2010 doesn’t recognize these attributes.  Therefore, if you attempt to call a method using these attributes, inside the project that defines the method, without specifying the parameter, the IDE will show a syntax error.  The compiler itself, however, will work correctly.  I reported this bug on Connect.

The [DefaultParameterValue] attribute is optional; omitting it will use the type’s default value (0, an empty struct, or null, as appropriate) as the default.

These attributes can also be used to create methods with optional parameters using CodeDOM, which cannot emit the new syntax.

0 comments:

Post a Comment