私が作成しているDynamicMethodで「操作によりランタイムが不安定になる可能性がある」という理由を発見しました。簡単に修正できましたが、一見単純な質問が残りました。
- 「Object」型のオブジェクト参照を特定の型にキャストして、オブジェクト参照でその型からメソッドを呼び出せるようにするにはどうすればよいですか?
以下はサンプルプログラムです。これを実行すると、メソッドのコンパイル時に「操作によりランタイムが不安定になる可能性があります」という例外でクラッシュします。
この問題は、宣言されている変数の型を のTestClass
代わりに型に変更するだけで修正されますObject
が、コード内の適切な型への参照をキャストする方法を知りたいです。
コードでは、アスタリスクで行をマークしました。メソッド呼び出しが通過するように、代わりにObject
スタック上の参照を参照にするその時点で、コードから何を発行できますか?TestClass
問題を引き起こすのはメソッド呼び出しであることを知っていることに注意してください。行を完全にコメントアウトすると、変数の型は関係ありません。メソッドはコンパイルされ、正常に実行されます。
これがコードです。
using System;
using System.Reflection.Emit;
namespace ConsoleApplication9
{
public class TestClass
{
public void TestMethod() { }
}
class Program
{
static void Main(string[] args)
{
Type type = typeof(TestClass);
DynamicMethod method = new DynamicMethod("", typeof(Object), null);
ILGenerator il = method.GetILGenerator();
LocalBuilder variable = il.DeclareLocal(typeof(Object));
// Construct object
il.Emit(OpCodes.Newobj, type.GetConstructor(new Type[0]));
il.Emit(OpCodes.Stloc, variable);
// Call Test method
il.Emit(OpCodes.Ldloc, variable);
// ***************************************** what do I do here?
il.Emit(OpCodes.Call, type.GetMethod("TestMethod"));
// Return object
il.Emit(OpCodes.Ldloc, variable);
il.Emit(OpCodes.Ret);
// Create and call delegate
Func<Object> fn = (Func<Object>)method.CreateDelegate(
typeof(Func<Object>));
Object instance = fn();
}
}
}