March 14, 2010

C# 4.0: Reflecting Named & Optional Parameters

I wrote few tests to understand Named and Optional Parameters. Now it's time to reflect.
I wrote few tests to see the what happens behind the scene.

Tests.
1. Reflecting Optional with default values
public void MethodWithDefaultValue(string name ="N/A", int cound =50)
 {
 
 }
gets converted to
public void MethodWithDeffaults([Optional, DefaultParameterValue("N/A")] string name, 
[Optional, DefaultParameterValue(50)] int count) 
{
}
You can declare a method using Optional Attribute, which allows you to have optional reference objects.

2. Reflecting Optional parametes when ommitted : When above method is called
public void ReflectMethodSignatureForOptionalWithDefaultValue()
{
ReflectClass optionalWithDefaultValue = new ReflectClass();
optionalWithDefaultValue.MethodWithDefaults();
}
gets converted to
public void ReflectMethodSignatureForOptionalWithDefaultValue()
{
new ReflectClass().MethodWithDefaults("N/A", 50);
}
Default values for the optional arguments are injected in the caller code.

3. Reflecting Named Parameters: if method in Test 1 called with named parameters,
public void ReflectNamedParametersCallerCode()
{
   ReflectClass optionalWithDefaultValue = new ReflectClass();
  optionalWithDefaultValue.MethodWithDefaults(count: 20, name: "Hello");
}
gets converted to
public void ReflectNamedParametersCallerCode() 
{ 
 ReflectClass optionalWithDefaultValue = new ReflectClass();
 int CS$0$0000 = 20;
string CS$0$0001 = "Hello";
optionalWithDefaultValue.MethodWithDefaults(CS$0$0001, CS$0$0000);
}
In the caller code,  A  local variable is created for every named parameter.
Complete Listing: In case you want to see yourself in reflector. Mouse hover on the listing to see clipboard/view source options.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace episodes
{
    
    public  class ReflectingNamedOptionalParams
    {
        public void ReflectMethodSignatureForOptionalWithDefaultValue()
        {
            ReflectClass optionalWithDefaultValue = new ReflectClass();
            optionalWithDefaultValue.MethodWithDefaults();
        }
        public void ReflectNamedParametersCallerCode()
        {
            ReflectClass optionalWithDefaultValue = new ReflectClass();
            optionalWithDefaultValue.MethodWithDefaults(count: 20, name: "Hello");
        }
    }

    public class ReflectClass
    {
        public void MethodWithDefaults(string name="N/A",int count=50)
        {
            
        }
    }
}