【发布时间】:2020-05-05 19:12:17
【问题描述】:
我正在将一些旧代码从 AS3(通过 Haxe)移植到 C#。
部分代码已转译,其他部分我用 C# 手动重写。这些部分之一是事件分派。
我有事件监听器注册到事件调度器,所有监听器都有这样的签名:
public void handleSomething(Event e)
// they may also use a subclass of Event as a parameter
public void handleAnother(MouseEvent e)
事件保留少量数据和类型:
public class Event {
public const string ENTER_FRAME = "enter_frame";
public const string RESIZE = "resize";
public const string CHANGE = "change";
readonly string type;
public Event(string type) {
this.type = type;
}
}
我保留一个以特定事件类型(字符串,由于遗留原因)为键的列表,一旦事件被调度,我会找到以该字符串为键的适当处理程序并使用事件数据调用它们。
我目前正在使用反射来执行此操作,但事实证明它非常缓慢。我发现 several threads 共享这个问题。
我的特殊问题是方法签名会有所不同,如果它始终是 Event 作为参数,我可以使用提供的解决方案,但是唉。
我可以在设置时交易一些内存/时间以使后续调用更快。我可以获得对该方法的引用并计算出它期望的类型,但我不确定以后如何存储和调用它?
【问题讨论】:
-
Reflection.Emit 在这种情况下可能会有所帮助,如果它只是一个函数调用,那么它应该相当容易。或者,如果您有少量案例,您可以在该字典中存储您自己的委托(您在填充字典时创建),它接受一个通用参数并在调用侦听器之前将其转换为适当的(是的,它甚至添加了另一个层,但与 pure 反射相比它相当快)。
-
将其移植到 dotnet 中的板载 Event System 不是一种选择? (或者也许你可以从中得到“启发”……)
-
@Fildor 遗憾的是,这在遗留代码中嵌入得太深了,无法进行这样的更改
-
@grapefrukt 这太糟糕了,但我有点期待这样的事情。无论如何 - 也许看看它以获得灵感他们是如何做到的。我想任何可以在没有反射的情况下完成的部分都应该提高性能......
标签: c# reflection