C#events-反射有什么方法可以区分简单事件和那些带有add{…}remove{…}的事件?

C#events-反射有什么方法可以区分简单事件和那些带有add{…}remove{…}的事件?,c#,events,reflection,add,compiler-generated,C#,Events,Reflection,Add,Compiler Generated,好吧,我刚要在这里发帖的时候就解决了这个问题。 我在寻找一种方法来区分像事件动作测试1和事件操作testEvt1{add{}remove{}带有反射,因为它们最终都是一对add_testEvt1 remove_testEvt1方法。令人惊讶的是,CompilerGenerateAttribute在这里没有帮助 结果证明,解决方案是查找与事件同名的私有备份字段——编译器只为简单事件生成一个备份字段,不允许其他字段具有相同的名称 正如代码所示: class Program {

好吧,我刚要在这里发帖的时候就解决了这个问题。 我在寻找一种方法来区分像
事件动作测试1
事件操作testEvt1{add{}remove{}
带有反射,因为它们最终都是一对add_testEvt1 remove_testEvt1方法。令人惊讶的是,CompilerGenerateAttribute在这里没有帮助

结果证明,解决方案是查找与事件同名的私有备份字段——编译器只为简单事件生成一个备份字段,不允许其他字段具有相同的名称

正如代码所示:

class Program
    {
        static void Main(string[] args)
        {
            EventInfo evt1 = typeof(a).GetEvent("testEvt1");
            EventInfo evt2 = typeof(a).GetEvent("testEvt2");

            var evt1Attrib = Attribute.GetCustomAttribute(evt1, typeof(CompilerGeneratedAttribute));
            var evt2Attrib = Attribute.GetCustomAttribute(evt2, typeof(CompilerGeneratedAttribute));

            var evt1Backfield = typeof(a).GetField(evt1.Name,BindingFlags.NonPublic | BindingFlags.Instance);
            var evt2Backfield = typeof(a).GetField(evt2.Name, BindingFlags.NonPublic | BindingFlags.Instance);
        }
    }

    public class a
    {
        //private Action testEvt1;
        public event Action testEvt1;
        public event Action testEvt2
        {
            add { }
            remove { }
        }
    }
evt1Attrib和evt2Attrib都以null结尾。但是,只能为简单的testEvt1找到支持文件,而不能为testEvt2找到支持文件


如果其他人碰巧也有同样的问题,我决定发表这篇文章,也许会问,有人知道区分testEvt1和testEvt2的更简单的方法吗?为什么编译器不添加CompilerGeneratedAttribute来添加和删除事件的方法?我想知道一种不依赖于支持字段命名规则的方法,这些规则将来可能会更改。

上述答案。您必须查找具有相同名称的私有实例或静态(与问题中的事件相同)支持字段

顺便说一句,这被称为类似于字段的事件。应该补充的是,提供的解决方案取决于编译器未记录的实现细节。理论上,不能保证支持字段与事件具有相同的名称。更多信息在此线程是。我写了一部分“我想知道一种方法,它不依赖于支持字段命名规则,将来可能会改变。”记住这一点。抱歉,如果结果有点晦涩。我建议你把你的问题改回原处,把这篇文章改成实际的解决方案,并接受它作为答案。这样,问题和解决方案之间就有了分离,问题将被标记为已回答。