【问题标题】:retrieve internal member of an internal nested class by reflection通过反射检索内部嵌套类的内部成员
【发布时间】:2012-06-01 13:51:44
【问题描述】:

好的,感谢ILSpy,我知道 MenuItem 类包含一个名为 MenuItemDatainternal 类,它自身包含一个 onDrawItem 的strong>内部成员。

给定一个 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 函数。有什么线索吗?

----编辑----

我的目标是删除 menuItem 的基本事件处理程序,名为DrawItem。请参阅接受的答案中的this post 和函数RemoveClickEvent,以便更好地理解。

【问题讨论】:

  • 那不是 C#,那是 Visual Basic。它仍然是视觉工作室,但标签是错误的。
  • 我添加了 C# 标签,这样如果有人在 C# 中有答案,他可以添加它

标签: c# vb.net winforms reflection internal


【解决方案1】:
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 的定义类似于 MenuItemData 中的定义:internal DrawItemEventHandler onDrawItem;
  • 您缺少 GetField 绑定标志,并且 mType 可能不是正确的嵌套类。我更新了答案
  • 我添加了 GetField 绑定标志,我得到了同样的错误。顺便说一句,我已经设法检索到与 onDrawItem 对应的 fieldInfo。我需要的是传递给 fi.GetValue 的正确参数
  • 要获取值,您需要引用 MenuitemData 的实例。为此,您需要通过 MenuItem 实例中数据字段的 GetValue 获取值并使用它。
  • 问题是menuItemData是作为类型返回的,不是作为字段也不是属性...
【解决方案2】:

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.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 2015-10-14
    • 2014-12-04
    • 1970-01-01
    相关资源
    最近更新 更多