当我坐在断点上的时候,我在眼前的窗口中输入了所有这些:
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的实际委托变量(它有两个已注册的侦听器,通过对具有该类型事件的对象进行反射而获得):
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}为了更好的衡量:
((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呢?
发布于 2016-03-14 21:46:17
首先,让我澄清一个误解:
((MulticastDelegate)l).GetType()如果l是MulticastDelegate或任何衍生产品,则这一行相当于:
l.GetType()因为GetType将检索引用的运行时类型。
现在,您真正的问题与代表无关,而与反射的一般工作方式有关。
当检索给定类型的字段并使用NonPublic时,将返回相关类型的私有字段,但不返回类型层次结构中任何类型的字段。反射类型是您调用GetFields的类型。
这种行为的原因是,子类型可以在超级类型中声明具有与私有字段相同名称的私有字段。这是必须的,因为不能期望子类型知道任何其他类的私有成员,包括它们的超级类型。您可以始终“重新声明”私人成员。
尝试使用以下代码:
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,它执行以下操作:
指定应返回层次结构上的公共和受保护的静态成员。继承类中的私有静态成员不会返回。静态成员包括字段、方法、事件和属性。不返回嵌套类型。
但这对你没什么帮助。如果您想列出所有私有字段,则必须手动提升类型层次结构。
https://stackoverflow.com/questions/35998516
复制相似问题