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

时间:2012-06-01 13:51:44

标签: c# vb.net winforms reflection internal

好的,感谢ILSpy,我知道 MenuItem 类包含名为 MenuItemData 内部类,其中包含自身名为 onDrawItem 内部成员。

给定一个MenuItem,我想检索对应于成员onDrawItem的对象。但我所要做的就是获取FieldInfo,而不是对象本身。

这是我的代码:

            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)

当到达最后一行时,我收到一个错误,上面写着这样的内容(它被引用):

  

'System.Windows.Forms.MenuItem + MenuItemData'类型中定义的'onDrawItem'字段不是'System.Windows.Forms.MenuItem

类型的目标对象的字段

我不知道在最后一行传递给GetValue函数的对象是什么。任何线索?

---- ---- EDIT

我的目标是删除 menuItem的基本eventHandler,名为 DrawItem 。有关更好的理解,请参阅接受的答案中的this post和函数RemoveClickEvent

2 个答案:

答案 0 :(得分:2)

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的实例。为此,您需要通过GetValue实例中data字段的MenuItem获取值并使用该值。

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);

答案 1 :(得分:0)

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)

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

更新 This page might also help.