通过反射检索内部嵌套类的内部成员

本文关键字:内部 成员 嵌套 反射 检索 | 更新日期: 2023-09-27 18:35:56

好的,多亏了ILSpy,我知道MenuItem类包含一个名为MenuItemData的内部类,该类包含一个名为onDrawItem的内部成员。

给定一个 MenuItem,我想检索与成员 onDrawItem 对应的对象。但我所能做的就是获取字段信息,而不是对象本身。

这是我的代码:

            Dim obj As Object
            Dim fi As FieldInfo
            Dim item as System.Windows.Forms.MenuItem
            Dim mType As System.Type
            mType = item.GetType()
            mType = mType.GetMember("MenuItemData", BindingFlags.NonPublic)(0)
            fi = mType.GetField("onDrawItem", BindingFlags.Static Or BindingFlags.Instance Or BindingFlags.NonPublic)
            obj = fi.GetValue(item)

到达最后一行时,我收到一个错误,说这样的话(它被traduced):

在类型"System.Windows.Forms.MenuItem+MenuItemData"中定义的字段"onDrawItem"不是类型为"System.Windows.Forms.MenuItem "的目标对象的字段

我不知道要传递给最后一行的 GetValue 函数什么对象。有什么线索吗?

----编辑----

我的目标是删除菜单项的基本事件处理程序,名为 DrawItem。请参阅这篇文章和已接受答案中的函数RemoveClickEvent,以便更好地理解。

通过反射检索内部嵌套类的内部成员

System.Type menuItemType = typeof(System.Windows.Forms.MenuItem);
System.Type menuItemDataType = menuItemType.GetNestedType("MenuItemData",
    System.Reflection.BindingFlags.NonPublic);
System.Reflection.FieldInfo fieldInfoOnDrawItem= menuItemDataType.GetField("onDrawItem", 
    System.Reflection.BindingFlags.NonPublic | 
    System.Reflection.BindingFlags.Instance |
    System.Reflection.BindingFlags.GetField ); 

另外:要获取该值,您需要引用MenuItemData实例。为此,您需要通过MenuItem实例中的data字段GetValue获取值并使用它。

System.Windows.Forms.MenuItem menuItem = new System.Windows.Forms.MenuItem();
System.Reflection.FieldInfo fieldInfoData = menuItemType.GetField("data",
    System.Reflection.BindingFlags.NonPublic |
    System.Reflection.BindingFlags.Instance |
    System.Reflection.BindingFlags.GetField);
object dataField = fieldInfoData.GetValue(menuItem);
object onDrawItem = fieldInfoOnDrawItem.GetValue(dataField);

onDrawItem 应该是一个事件,特别是考虑到对其声明类型的注释。 我在MSDN上找到了这个页面,它应该能够帮助你。

Dim tExForm As Type = assem.GetType("ExampleForm")
Dim exFormAsObj As Object = Activator.CreateInstance(tExForm)
Dim evClick As EventInfo = tExForm.GetEvent("Click")
Dim tDelegate As Type = evClick.EventHandlerType
Dim miHandler As MethodInfo = GetType(Example).GetMethod("LuckyHandler", BindingFlags.NonPublic Or BindingFlags.Instance)

最后一点应该是对你最有用的。 获取链接到事件的方法的方法信息,然后可以使用这些信息触发方法或链接到该方法。

更新此页面也可能有所帮助。