Value-Type Parameters in Reflection

March 23rd 2011 Reflection .NET Framework

It seems that no matter how much experience one has with .NET framework, there are still surprises awaiting him somewhere down the road. This time I'd like to point out an interesting behavior of MethodInfo.Invoke many of you might not be aware of. I certainly wasn't, until today.

Since this is well documented, I should start with a quote from the documentation for the parameters parameter:

An argument list for the invoked method or constructor. [...] Any object in this array that is not explicitly initialized with a value will contain the default value for that object type. For reference-type elements, this value is null. For value-type elements, this value is 0, 0.0, or false, depending on the specific element type.

What exactly does this mean? If you pass a null as a value for a value-type parameter, the call won't fail as you might have expected. Instead, the default value for that type will be set as the parameter value.

The following short sample demonstrates this behaviour:

public void WriteValue(int value)
{
    Console.WriteLine("value = {0}", value);
}

public static void Main(string[] args)
{
    // this will result in a compile error:
    // Argument 1: cannot convert from '<null>' to 'int'
    WriteValue(null);

    // this will output:
    // value = 0
    Type type = typeof(Program);
    MethodInfo method = type.GetMethod("WriteValue");
    method.Invoke(new Program(), new object[] { null });

    // this will throw a RuntimeBindingException:
    // The best overloaded method match for 'Program.WriteValue(int)' 
    //     has some invalid arguments
    dynamic obj = new Program();
    obj.WriteValue(null);
}

Obviously calling the method directly with a null value won't even compile (unless you change the parameter type to Nullable<int>). The Reflection based call succeeds by passing the default value (0 for int) as the parameter value. The dynamic type doesn't exhibit this behavior – the call fails with a runtime exception.

Copyright
Creative Commons License