Emit(OpCodes.Ldfld,textBox)因转换而失败

时间:2015-04-13 01:51:27

标签: c# casting textbox emit

我正在使用Reflection.Emit构建一个简单的动态方法,该方法在简单的WPF程序(MyTextBox.Text)中获取TextBox对象的Text属性值。

使用Invoke无法正确调用此动态方法,我在此行发现了错误的内容' Emit(OpCodes.Ldfld,textBox)'感谢VisualStudio.DebuggerVisualizers。

以下是调试时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。它看起来像这样:.locals init([0] string a)IL_0000:nop IL_0001:ldarg.0 IL_0002:ldfld class [PresentationFramework] System.Windows.Controls.TextBox MyWPFTest.MainWindow1 :: MyTextBox IL_0007:callvirt instance string [PresentationFramework ] System.Windows.Controls.TextBox :: get_Text()IL_000c:stloc.0 IL_000d:ret} //方法结束MainWindow1 :: MyTextBox_TextChanged

1 个答案:

答案 0 :(得分:0)

如果您阅读the example on MSDN,则您发现默认情况下参数列表中不包含this个参数。指定owner的{​​{1}}类可以访问私有成员,但不能访问DynamicMethod参数。您的DynamicMethod就像C#源代码中的this方法。

现在你有一个空数组的参数类型,所以没有static

尝试指定参数类型。变化

Ldarg_0

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