Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle null parameters while calling a method using Reflection

I'm trying to write code that will infer types from a parameter list and then call the method that matches those parameters. This works very well, except when the parameter list has a null value in it.

I am wondering how I might cause the Type.GetMethod call to match a function/overload, even with a null parameter in the parameters list.

object CallMethodReflection(object o, string nameMethod, params object[] args)
{
    try
    {
        var types = TypesFromObjects(args);
        var theMethod = o.GetType().GetMethod(nameMethod, types);
        return (theMethod == null) ? null : theMethod.Invoke(o, args);
    }
    catch (Exception ex)
    {
        return null;
    }
}
Type[] TypesFromObjects(params object[] pParams)
{
    var types = new List<Type>();
    foreach (var param in pParams)
    {
        types.Add((param == null) ? null : param.GetType());
    }
    return types.ToArray();
}

The main problem line is the types.Add((param == null) ? null : param.GetType());, which will cause the GetMethod call to fail with a null value in the types array.

void Function1(string arg1){ }
void Function1(string arg1, string arg2){ }
void Function1(string arg1, string arg2, string arg3){ }
void Function2(string arg1){ }
void Function2(string arg1, int arg2){ }
void Function2(string arg1, string arg2){ }

/*1*/ CallMethodReflection(obj, "Function1", "String", "String"); // This works
/*2*/ CallMethodReflection(obj, "Function1", "String", null); // This doesn't work, but still only matches one overload
/*3*/ CallMethodReflection(obj, "Function2", "String", "String"); // This works
/*4*/ CallMethodReflection(obj, "Function2", "String", null); // This doesn't work, and I can see why this would cause problems

Mainly, I'm trying to determine how to change my code so that line /*2*/ works as well.

like image 280
palswim Avatar asked May 11 '11 18:05

palswim


1 Answers

There are overrides to the GetMethod call which take an object derived from the Binder class. This allows you to override the default method binding and return the method you want to use, based on the actual parameters passed. This is essentially what the two other answers are doing as well. There is some sample code here:

http://msdn.microsoft.com/en-us/library/system.reflection.binder.aspx

like image 76
ScottTx Avatar answered Sep 18 '22 13:09

ScottTx