2

I am currently writing some code which uses MethodInfo.Invoke() to execute a method using reflection. I need to catch exceptions if they occur, and do not want to edit any Visual Studio exception handling settings to do so.

I have read other StackOverflow articles (Reflection MethodInfo.Invoke() catch exceptions from inside the method and How can I create an Action delegate from MethodInfo?) which illustrate the ability to unwrap the invocation by creating a delegate, and executing that instead of calling Invoke().

The problem I have is that I don't know the method signature of the method I am calling; It could have a return type, or return void, and it could have several parameters, or none.

Consider the following code:

public void Run(object instance, MethodInfo method)
{
    object[] parameters = CreateParameters(method);
    object result = default(object);
    try
    {
        result = method.Invoke(context, parameters);
    }
    catch(Exception ex)
    {
        // Never happens because VS does not catch exceptions thrown by Invoke();
    }
}

Given this scenario, I'm stuck with exactly how to create an appropriate Action<Tᴺ> or Func<Tᴺ, out TResult> (where ᴺ == number of parameters)

Community
  • 1
  • 1
Matthew Layton
  • 39,871
  • 52
  • 185
  • 313
  • 1
    I'm not sure I understand. You want to write a bunch of code (this is not trivial) so you don't have to change a debugger setting? – Mike Zboray Dec 11 '14 at 09:23
  • @mikez - correct...Personally I don't give a damn about the setting, but the end user running this code will care, and ultimately this code will be unusable to the end user! – Matthew Layton Dec 11 '14 at 09:24
  • But the debugger setting has no effect what happens to the end user. – Mike Zboray Dec 11 '14 at 09:25
  • @mikez it does because the end user would have to disable the setting too. They should not need to do so, nor spend ages trawling the web to find out why and how to do so...as I said, the code would be unusable - the aim here is to catch the exceptions regardless of a visual studio debugger setting – Matthew Layton Dec 11 '14 at 09:28
  • Are you providing the user source code? The default behavior is to break on "Just my code", so some one compiling against your library doesn't see your internally handled exceptions. – Mike Zboray Dec 11 '14 at 09:32
  • @mikez I am providing the binary, however they may execute against source code, which means that if their code throws exceptions, my code will not handle them...it will break to the exception thrown by the users code in the IDE – Matthew Layton Dec 11 '14 at 09:33

1 Answers1

2

create a dynamic method to do job and create a delegate from your dynamic method.

for exemple, imagine a method

static public int Add(int a, int b)
{
    return a+b;
}

emit method with DynamicMethod doing this :

static public object Add(object[] parameters)
{
    return Add((int)parameters[0], (int)parameters[1]);
}

and create delegate to emitted method.

var myDelegate = MyDynamicMethod.CreateDelegate(typeof(Func<object[], object>)) as Func<object[], object>:

You have to use reflection to know signature in order to emit the adequat DynamicMethod.

Teter28
  • 504
  • 5
  • 8