Подтвердить что ты не робот

Reflection MethodInfo.Invoke() catch исключений изнутри метода

У меня есть вызов MethodInfo.Invoke() для выполнения функции посредством отражения. Вызов завернут в блок try/catch, но он все равно не поймает исключение, вызванное вызываемой мной функцией.

Получаю следующее сообщение:

Исключение не было обработано пользователем.


Почему MethodInfo.Invoke() предотвращает исключение Exception за пределами Invoke()?
Как это сделать?

4b9b3361

Ответ 1

РЕДАКТИРОВАТЬ: Насколько я понимаю вашу проблему, проблема - это только IDE; вам не нравится, что VS обрабатывает исключение, вызванное вызовом MethodInfo как неотображенное, когда это явно не так. Вы можете прочитать о том, как решить эту проблему здесь: Почему TargetInvocationException рассматривается как непроверенный с помощью IDE? Кажется, это ошибка/по дизайну; но так или иначе, достойные обходные пути перечислены в этом ответе.

Как я вижу, у вас есть несколько вариантов:

  • Вы можете использовать MethodInfo.Invoke, поймать TargetInvocationException и проверить его свойство InnerException. Вам придется обходить проблемы IDE, как указано в этом ответе.

  • Вы можете создать соответствующий Delegate из MethodInfo и вместо этого вызвать это. С помощью этой техники исключенное исключение не будет обернуто. Кроме того, этот подход, похоже, хорошо работает с отладчиком; Я не получаю всплывающие окна "Uncaught exception".

Вот пример, который подчеркивает оба подхода:

class Program
{
    static void Main()
    {
        DelegateApproach();
        MethodInfoApproach();
    }

    static void DelegateApproach()
    {
        try
        {
            Action action = (Action)Delegate.CreateDelegate
                                   (typeof(Action), GetMethodInfo());
            action();
        }
        catch (NotImplementedException nie)
        {

        }
     }

    static void MethodInfoApproach()
    {
        try
        {
            GetMethodInfo().Invoke(null, new object[0]);
        }
        catch (TargetInvocationException tie)
        {
            if (tie.InnerException is NotImplementedException)
            {


            }
        }
    }

    static MethodInfo GetMethodInfo()
    {
        return typeof(Program)
                .GetMethod("TestMethod", BindingFlags.NonPublic | BindingFlags.Static);
    }    

    static void TestMethod()
    {
        throw new NotImplementedException();
    }
}

Ответ 2

Как вы пытаетесь поймать исключение? Как правило, то, что выбрано из вызова Invoke(), является экземпляром исключения для оболочки System.Reflection.TargetInvocationException. Фактическое исключение вы будете в InnerException.

try
{
    method.Invoke(target, params);
}
catch (TargetInvocationException ex)
{
    ex = ex.InnerException; // ex now stores the original exception
}