gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 23:19:17 26 4
gpt4 key购买 nike

我在断点处在即时窗口中输入所有这些:

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 类型的实际委托(delegate)变量(它有两个注册的监听器,通过反射具有该类型事件的对象获得):

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

最佳答案

首先澄清一个误会:

((MulticastDelegate)l).GetType()

如果 lMulticastDelegate 或任何派生类,则此行等同于:

l.GetType()

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


现在,您真正的问题与委托(delegate)无关,而与反射的一般工作方式有关。

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

此行为的原因是子类型可以声明与父类(super class)型中的私有(private)字段同名的私有(private)字段。这是必须的,因为不能期望子类型知道任何其他类的私有(private)成员是什么,包括它们的父类(super class)型。您可以始终“重新声明”私有(private)成员。

用下面的代码试试:

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,它执行以下操作:

Specifies that public and protected static members up the hierarchy should be returned. Private static members in inherited classes are not returned. Static members include fields, methods, events, and properties. Nested types are not returned.

但这对你没有帮助。如果您想列出所有私有(private)字段,则必须手动在类型层次结构中向上移动。

关于c# - 为什么反射不能访问 MulticastDelegate 变量中的 _invocationList/_invocationCount 字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35998516/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com