I have recently downloaded the Visual Studio 2010 Beta 1 and started looking into the .NET Framework 4.0/IDE features.In the next couple of posts I will be discussing about these.To start with I have chosen optional parameters and default values.This feature is nothing new and has been there in languages like C++ for quite long.We will first take a look how we can use this in C# and how it is implemented.The following lines of C# code shows a method where the parameter middleName is optional and client is forced to pass a blank string value there as the parameter is not optional.
class Program {
static void Main(string[] args) {
Foo f = new Foo();
f.PrintName("Sankarsan", "", "Bose");
Console.ReadLine();
}
}
public class Foo {
public void PrintName(string firstName, string middleName, string lastName) {
Console.WriteLine("Name is {0}{1}{2}", firstName, middleName, lastName);
}
}
In C# 4.0 we can specify a default value for the parameter middleName and make it optional parameter as shown below.
public void PrintName(string firstName, string middleName=string.Empty, string lastName) {
Console.WriteLine("Name is {0}{1}{2}", firstName, middleName, lastName);
}
This code will not compile and throw the error,Optional parameters must appear after all required parameters.This is Rule#1: we have to define all the optional parameters after required parameters they cannot appear in between some required parameters.
So the let’s change the parameter ordering as shown below:
public void PrintName(string firstName, string lastName,string middleName=string.Empty) {
Console.WriteLine("Name is {0}{1}{2}", firstName, middleName, lastName);
}
This time I get another compilation error,Default parameter value for ‘middleName’ must be a compile-time constant.This is Rule#2:we have to use compile time constant as default values.So we alter the code as,
public void PrintName(string firstName, string lastName,string middleName="") {
Console.WriteLine("Name is {0} {1} {2}", firstName, middleName, lastName);
}
This code will work fine and print “Name is Sankarsan Bose”.
Let us take a look at the IL code to find out what’s going on behind the scenes.The IL code for PrintName is shown below:
.method public hidebysig instance void PrintName(string firstName,
string lastName,
[opt] string middleName) cil managed
{
.param [3] = “”
// Code size 16 (0×10)
.maxstack 8
IL_0000: nop
IL_0001: ldstr “Name is {0} {1} {2}”
IL_0006: ldarg.1
IL_0007: ldarg.3
IL_0008: ldarg.2
IL_0009: call void [mscorlib]System.Console::WriteLine(string,
object,
object,
object)
IL_000e: nop
IL_000f: ret
} // end of method Foo::PrintName
The [opt] indicates this is an optional argument and param[3]=”" provides the default value.The IL code of the main function will look something like this:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 36 (0×24)
.maxstack 4
.locals init ([0] class CSharp40Demo.Foo f)
IL_0000: nop
IL_0001: newobj instance void CSharp40Demo.Foo::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldstr “Sankarsan”
IL_000d: ldstr “Bose”
IL_0012: ldstr “”
IL_0017: callvirt instance void CSharp40Demo.Foo::PrintName(string,
string,
string)
IL_001c: nop
IL_001d: call string [mscorlib]System.Console::ReadLine()
IL_0022: pop
IL_0023: ret
} // end of method Program::Main
Take note of the lines marked in bold.The compiler is checking the method signature of PrintName and generating IL code to call a method with 3 parameters and passing the default value as the argument.So this again is nothing but a syntactical sugar coat.
If we add one more method with same name and two string parameters as shown below, which method will be called?.
public void PrintName(string firstName, string lastName) {
Console.WriteLine("PrintName2::Name is {0} {1}", firstName, lastName);
}
Here we are calling PrintName with two arguments so .The output is PrintName2::Name is Sankarsan Bose, the method without optional parameters will be considered in this case.
This is all about optional parameters, in the next post we will discuss about named arguments.

