12

このコードは「出力値」を出力します。

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();
  }
}

リフレクションを使用するときに「出力値」と例外の両方を取得するにはどうすればよいですか?

4

5 に答える 5

1

この例外は、[out] 値をスタック フレームからオブジェクト配列にコピーする MethodInfo.Invoke() のコードをバイパスしました。Invoke() が作成したスタック フレームの値は、最初のスニペットと同じように動作します。しかし、類似点はここまでです。

于 2010-01-20T11:33:59.410 に答える
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;
            }
        }
}
于 2010-01-20T11:55:40.843 に答える
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);        
}
于 2010-01-20T14:20:56.047 に答える
0

out パラメータの代わりに Result オブジェクトを返すようにメソッドを変更することを提案します。結果オブジェクトには、例外と引数の値を含めることができます。

于 2010-01-20T11:57:19.217 に答える
-1

メソッドが例外をスローした場合、out パラメータは未定義です。これは、最初の例で null に初期化しないことで確認できます。そうすると、コードはコンパイルされません。

したがって、メソッドが例外をスローした場合に、Invoke メソッドが未定義の値を返さないことは理にかなっています。

于 2010-01-20T11:06:23.403 に答える