Reflection.Emit を使用して、単純な WPF プログラム (MyTextBox.Text) で TextBox オブジェクトの Text プロパティ値を取得する単純な動的メソッドを構築しています。
この動的メソッドは Invoke で正しく呼び出すことができず、VisualStudio.DebuggerVisualizers のおかげで、この行 'Emit(OpCodes.Ldfld, textBox)' で何か問題があることがわかりました。
デバッグ中の ILStream の出力は次のとおりです。
IL_0000: /* 02 | */ ldarg.0
IL_0001: /* 7b | 04000002 */ ldfld **!"Specified cast is not valid."!**
IL_0006: /* 28 | 06000003 */ call System.String get_Text()/System.Windows.Controls.TextBox
IL_000b: /* 2a | */ ret
コードは次のとおりです。
namespace MyWPFTest
{
public partial class MainWindow1 : Window
{
public MainWindow1()
{
InitializeComponent();
}
private void MyTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
MyTextBox.Text = "Morning";
DynamicMethod dm = new DynamicMethod("GetTextBoxText", typeof(void), new Type[] { }, typeof(MainWindow1), false);
ILGenerator il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
FieldInfo textBox = typeof(MainWindow1).GetField("MyTextBox", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
if (textBox == null)
{
throw new InvalidOperationException("no textbox");
}
il.Emit(OpCodes.Ldfld, textBox);
var textProperty = typeof(TextBox).GetProperty("Text", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).GetGetMethod();
if (textProperty == null)
{
throw new InvalidOperationException("no Text property");
}
il.Emit(OpCodes.Call, textProperty);
il.Emit(OpCodes.Ret);
TestShowVisualizer(dm);
dm.Invoke(null, null);
}
}
}
TestSHowVisulalizer()
デバッグ用の IL ストリームを表示するのに役立ちます。
TextBox のような WPF コントロールを Reflection.Emit で動作させる経験がある人はいますか?
このコード「var a = MyTextBox.Text」を書き、ilsdasm を使用して il を取得しました。次のようになります。 ]System.Windows.Controls.TextBox::get_Text() IL_000c: stloc.0 IL_000d: ret } // メソッドの終了 MainWindow1::MyTextBox_TextChanged