Pages

Wednesday, December 19, 2012

Default parameters in delegates and reflection

Recently I have refactored a method. It was created in C# 2.0 and it was overriden many times to support default parameters, something like this:

public void Foo()
{
    Foo(0);
}

public void Foo(int arg1)
{
    Foo(arg1, "");
}

public void Foo(int arg1, string arg2)
{
    //finally, do something
}

But we have migrated to C# 4.0, so it is better to use actual default parameters, like this:

public void Foo(int arg1 = 0, string arg2 = "")
{
    //do something
}

However there are 2 questions. How it will work with delegates and how it will work with reflections. The answers are simple. You have to declare delegate with default parameter and for reflection you can use Type.Missing object. Here are 2 examples:

About delegates:
void Foo(int arg1 = 0, string arg2 = "")
{
    //do something
}

void Foo2(int arg1, string arg2)
{
    //do something
}

void FooError(int arg1)
{
    //do something
}

delegate void FooDelegate(int arg1 = 0, string arg2 = "");

void SomeWhere()
{
    //you can declare delegates with default parameters:
    FooDelegate method = Foo;
            
    //and invoke them:
    method();
    method(arg1: 10);
    method(arg2: "string value");

    //and you can even use functions without defaut parameters:
    FooDelegate method2 = Foo2;

    method2();
    method2(1, "string");

    //but you cannot use method with different number of arguments:
    FooDelegate method3 = FooError; //Here is error!
    method3();
}

And about reflection:
void SomeWhere()
{
    Type myType = typeof(MyClass); //for simplicity I will get Type like this
    var myObj = Activator.CreateInstance(myType); //create instance of the class
    var myMethodInfo = myType.GetMethod("Foo"); //and get method info from Type

    // now we can invoke that method with Type.Missing parameter for default value
    myMethodInfo.Invoke(myObj, new object[] { Type.Missing, Type.Missing });
    myMethodInfo.Invoke(myObj, new object[] { 10, Type.Missing });
    //however the order of the parameters must be correct!
    myMethodInfo.Invoke(myObj, new object[] { Type.Missing, "string" });

    myMethodInfo.Invoke(myObj, new object[] { "string", Type.Missing }); //this will throw an error!
}

No comments:

Post a Comment