繁体   English   中英

C#反思:如何调用EventInfo?

[英]C# Reflection: How to invoke a EventInfo?

如何在EventInfo后面调用事件? 我尝试了以下操作,但“ GetRaiseMethod”始终为“ null”:

MethodInfo eventRaiseMethod = eventInfos[i].GetRaiseMethod();
eventRaiseMethod.Invoke(this, arrayOfPropertyChangedArgs);

谢谢 :)

更新:似乎多数民众赞成在C#中的错误???

EventInfo.GetRaiseMethod()始终为null

仅在实现事件而不覆盖add \\ remove的情况下,“调用”事件才有意义:

class Test {
    public event Action TestEvent;

    void Invoke() {
        // fine
        TestEvent();
    }
}

但是,使用自定义add \\ remove调用事件的概念没有意义:

class Test {
    public event Action TestEvent
    {
        add { }
        remove { }
    }

    void Invoke() {
        // does not compile, invoke what?
        TestEvent();
    }
}

因此,对于具有“默认”实现的事件,事件调用只是调用基础编译器生成的委托字段的语法糖。

知道这一点,您可以搜索该字段并调用它。 这是一个与事件同名的私有字段:

class Program {
    static void Main(string[] args) {
        var test = new Test();
        test.TestEvent += OnTest;            
        var backingField = typeof(Test).GetField("TestEvent", BindingFlags.Instance | BindingFlags.NonPublic);
        var delegateInstance = (Action)backingField.GetValue(test);
        delegateInstance();            
    }

    private static void OnTest() {
        Console.WriteLine("Event invoked");
    }
}

class Test {
    public event Action TestEvent;
}

也就是说,某些.NET语言的编译器可能会为自动实现的事件生成“提高”方法。 如果是这种情况, GetRaiseMethod将返回该方法。 C#编译器不会那样做。 因此,如果您想安全GetRaiseEvent ,则可以先调用GetRaiseEvent ,如果它返回null,则退回到现场方法。 当然,您应该期望该字段也为空(因为如上所述并非所有事件都可以调用-不需要该字段存在)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM