此代码输出“out value”。
class P
{
public static void Main()
{
string arg = null;
try
{
Method(out arg);
}
catch
{
}
Console.WriteLine(arg);
}
public static void Method(out string arg)
{
arg = "out value";
throw new Exception();
}
}
但这个没有。
class P
{
public static void Main()
{
object[] args = new object[1];
MethodInfo mi = typeof(P).GetMethod("Method");
try
{
mi.Invoke(null, args);
}
catch
{
}
Console.WriteLine(args[0]);
}
public static void Method(out string arg)
{
arg = "out value";
throw new Exception();
}
}
当使用反射时,如何同时获得“out value”和异常?
答案 0 :(得分:1)
异常绕过MethodInfo.Invoke()中的代码,该代码将堆栈帧中的[out]值复制回对象数组。 Invoke()创建的堆栈框架上的值与第1个代码段中的值相似。但这就是相似之处的结束。
答案 1 :(得分:1)
唯一的方法是以考虑异常可能性的方式重载您的方法,然后在“以防万一”中传递一个。以下产生我认为你正在寻找的东西。我理解的问题是反射不会直接操作通过引用传入的地址。在达到方法结束点之前,地址不会受到影响。可能是MS的内存保护或内存安全方案。
class P
{
public static void Main()
{
object[] args = { "1", new Exception()};
MethodInfo mi = typeof(P).GetMethod("Method");
try
{
mi.Invoke(null, args);
}
catch
{
}
Console.WriteLine(args[0].ToString());
Console.WriteLine(args[1].ToString());
}
public static void Method(ref string arg, ref Exception ex)
{
try
{
arg = "out value";
throw new Exception();
}
catch (Exception exc)
{
ex = exc;
}
}
}
答案 2 :(得分:0)
我建议更改方法以返回Result对象而不是out参数。 结果对象可以包含异常以及arg的值。
答案 3 :(得分:0)
如果出现问题,您如何发现异常已经发生并且您正在使用Windows窗体应用程序,您是否尝试过查看线程异常事件并将其与SetUnhandledExceptionMode()相结合?
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
HandleException(e.Exception);
}
答案 4 :(得分:-1)
如果方法抛出异常,则out参数未定义。您可以通过在第一个示例中将其初始化为null来看到这一点,然后代码将无法编译。
因此,如果方法抛出异常,则Invoke方法不返回未定义的值是有意义的。