C# - 通过反射 (SetValue()) 调用时无法捕获属性 setter 中引发的异常



我的问题类似于使用反射,setter 会抛出无法捕获的异常,但推荐的解决方案并不能解决我的问题。

在下面的代码中,我尝试通过两种不同的方式设置类的属性:第一种,直接,第二种,通过反射。资源库会抛出一个异常(在实际用例中,仅当给定的值无效时(,该异常应该在调用资源库的位置捕获。 但例外仅在第一个变体中捕获; 在第二个中,捕获块永远不会被执行。 这是什么原因呢?

在我的用例中,我想使用反射变体,但程序总是在抛出异常的地方终止,我没有更改来捕获它。

上面提到的线程建议调试器的配置方式使其在每个异常时都会中断(这种情况不能像第一个变体那样,异常被完全捕获(或异常来自其他地方。不幸的是,我不知道否则它会从哪里来。

非常感谢您的帮助!

using System;
using System.Reflection;
namespace ReflectionTestConsole
{
public class Program
{
public static void Main(string[] args)
{
Logic logic = new Logic();
try
{
logic.MyProperty = 5;
} 
catch(Exception e)
{   // in this case, the exception is caught here.
Console.WriteLine("Exception was caught: " + e.Message);
}
try{
PropertyInfo propInfo = logic.GetType().GetProperty("MyProperty");
propInfo.SetValue(logic,5);
}
catch (Exception e)
{   // in this case, the exception is not caught
Console.WriteLine(e.Message);
}
}
}
public class Logic
{
private double variable;
public double MyProperty
{
get
{
return variable;
}
set
{ //Check if value is valid and if not throw an exception
throw new Exception("This is the exception");
}
}
}
}

使用@Lutti Coelho和@HimBromBeere的评论以及这个线程,我找到了解决问题的方法:

1(我假设第二个异常(在反射调用中抛出(没有被捕获,是错误的。它被捕获,但我的控制台输出未正确显示它。

2(在SetValue(((oder GetValue(((反射调用中抛出的每个异常都包装在TargetInvocationException e中。真正的例外是e.InnerException。如果引发用户定义的异常并为此特定异常类型编写 catch-子句,这一点很重要。

理解了这两件事,代码在dotnetfiddle上按预期运行。但是,在Visual Studio中,调试器仍然在引发异常的位置终止,告诉我即使我在反射调用周围放置了一个try-catch块,异常仍未处理。

3(在这里,提到的线程帮助了我:Visual Studio有一个名为"仅我的代码"的设置(请参阅→调试→"仅启用我的代码"→"工具→选项"(。如果启用,它将在我的代码中未处理的每个异常时停止。就我而言,我的代码抛出了异常,但它让我的代码通过 C# 标准反射库,稍后才返回到我的代码。由于异常在离开我的代码时未处理,因此调试器在此时终止。 因此,在Visual Studio中禁用此设置最终解决了我的问题。

您的异常已引发。但正如它发生在SetValue方法中一样。例外情况在InnerException内。要获取您的特定异常,您需要调用e.InnerException

catch (Exception e)
{   
Console.WriteLine("Reflection exception was caught: " + e.InnerException.Message);
}

在简历中,您的Exception eSetValue方法引发的异常。由于另一个例外而引起,另一个例外是InnerException

您可以在以下位置看到一个工作示例: https://dotnetfiddle.net/i49ZQC

最新更新