首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么反射不能访问MulticastDelegate变量中的_invocationList/_invocationCount字段?

为什么反射不能访问MulticastDelegate变量中的_invocationList/_invocationCount字段?
EN

Stack Overflow用户
提问于 2016-03-14 21:33:04
回答 1查看 200关注 0票数 1

当我坐在断点上的时候,我在眼前的窗口中输入了所有这些:

代码语言:javascript
复制
typeof(MulticastDelegate).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
{System.Reflection.FieldInfo[6]}
    [0]: {System.Object _invocationList}
    [1]: {IntPtr _invocationCount}
    [2]: {System.Object _target}
    [3]: {System.Object _methodBase}
    [4]: {IntPtr _methodPtr}
    [5]: {IntPtr _methodPtrAux}

看起来不错,对吧?但是,让我们使用一个类型为EventHandler的实际委托变量(它有两个已注册的侦听器,通过对具有该类型事件的对象进行反射而获得):

代码语言:javascript
复制
l.GetType().Name
"EventHandler"
l is MulticastDelegate
true
l.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
{System.Reflection.FieldInfo[4]}
    [0]: {System.Object _target}
    [1]: {System.Object _methodBase}
    [2]: {IntPtr _methodPtr}
    [3]: {IntPtr _methodPtrAux}

为了更好的衡量:

代码语言:javascript
复制
((MulticastDelegate)l).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
{System.Reflection.FieldInfo[4]}
    [0]: {System.Object _target}
    [1]: {System.Object _methodBase}
    [2]: {IntPtr _methodPtr}
    [3]: {IntPtr _methodPtrAux}

为什么不能通过反思变量来访问_invocationList_invocationCount,而不能直接反映MulticastDelegate呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-14 21:46:17

首先,让我澄清一个误解:

代码语言:javascript
复制
((MulticastDelegate)l).GetType()

如果lMulticastDelegate或任何衍生产品,则这一行相当于:

代码语言:javascript
复制
l.GetType()

因为GetType将检索引用的运行时类型。

现在,您真正的问题与代表无关,而与反射的一般工作方式有关。

当检索给定类型的字段并使用NonPublic时,将返回相关类型的私有字段,但不返回类型层次结构中任何类型的字段。反射类型是您调用GetFields的类型。

这种行为的原因是,子类型可以在超级类型中声明具有与私有字段相同名称的私有字段。这是必须的,因为不能期望子类型知道任何其他类的私有成员,包括它们的超级类型。您可以始终“重新声明”私人成员。

尝试使用以下代码:

代码语言:javascript
复制
public class Program
{
    public static void Main()
    {
        var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
        Console.WriteLine(typeof(B).GetFields(flags).Length);
    }
}

public class A
{
    private int _foo;
}

public class B : A
{
    private int _bar;
}

输出值为1

请注意,BindingFlags有一个值FlattenHierarchy,它执行以下操作:

指定应返回层次结构上的公共和受保护的静态成员。继承类中的私有静态成员不会返回。静态成员包括字段、方法、事件和属性。不返回嵌套类型。

但这对你没什么帮助。如果您想列出所有私有字段,则必须手动提升类型层次结构。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35998516

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档