0

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

4

1 に答える 1

0

MSDN の例を読むと、this既定では引数リストに引数が含まれていないことがわかります。ownera のクラスを指定するDynamicMethodと、プライベート メンバーにアクセスできますが、this引数にはアクセスできません。DynamicMethod はstatic、C# ソース コードのメソッドのようなものです。

現在、引数タイプの空の配列があるため、Ldarg_0.

引数の型を指定してみてください。変化する

DynamicMethod dm = new DynamicMethod("GetTextBoxText",
                                     typeof(void),
                                     new Type[] { },
                                     typeof(MainWindow1),
                                     false);

DynamicMethod dm = new DynamicMethod("GetTextBoxText",
                                     typeof(void),
                                     new Type[] { typeof(MainWindow1) },
                                     typeof(MainWindow1),
                                     false);
于 2015-04-13T02:50:20.887 に答える