很久以前,我看到了一些允许你动态链接一系列方法的东西。不记得它是在C#还是C ++中。
它是这样的:
方法:
Foo();
Bar();
Moar();
然后创建一个对象,用于订阅(缺少更好的单词)上述任何或所有方法(取决于程序员的规范),并且传递给此对象的任何内容都将运行所有订阅的方法。
我问,因为我正在为一个程序的内核工作,这取决于各种选择,可能需要或可能不需要某些方法。由于这个程序需要非常紧密地编码(我不想在if / else语句上浪费处理器周期...它会加起来),我想知道是否有人回忆起我试图传达的内容,以及C#是什么相当于。
谢谢, -R
答案 0 :(得分:3)
听起来就像一个事件:
宣称:
public event Action Something;
订阅:
obj.Something += x.Foo;
...
obj.Something += y.Bar;
...
obj.Something += z.Moar;
然后调用:
protected virtual void OnSomething() {
var handler = Something;
if(handler != null) handler();
}
...
OnSomething(); // call ^^^^^^
会调用所有3种方法,但松散耦合。
请注意,只需使用 delagate 而不是事件,您就可以完全相同。另请注意,事件通常具有更具体的void (object sender, SomeEventArgs args)
签名(但这是惯例,而非要求)。
答案 1 :(得分:2)
Marc的答案是C#中最接近的答案,但值得指出 - 这不会比一系列if
更快,它会更慢。
也许您指的是在方法结束时{(1}}到汇编程序中的另一个地址的方式,以避免JMP
和后续的两个CALL
- 这是X86汇编程序,但现代优化编译器将为您进行优化。
也就是说,你用RET
调用一个方法,将返回地址推送到堆栈,然后在另一个方法的末尾,你可能CALL
另一个方法,但是它完成了,做了一个CALL
返回第一个结尾,RET
跳回原来的来电者。但是,在第一个末尾有一个RET
,它'链'到第二个,第二个方法的JMP
返回给调用者,节省了额外的跳转/一些堆栈操作。
根据您的目的,您可以使用框架的反射发射部分(http://msdn.microsoft.com/en-us/library/3y322t50.aspx)在.NET中动态生成代码。如果要以文本方式进行操作,还可以使用内置的C#编译器将方法动态编译到内存中。那可以成为你的想法。
答案 2 :(得分:0)
您能否回忆起某些API中“流畅”编码风格的一些片段?
每个函数都返回其对象实例作为函数结果,因此您可以将这样的调用链接在一起:
obj.Foo()
.Bar()
.Moar();
这里没有特别神奇的性能提升,它只是让你不必再次输入对象实例变量名。
好的,使用函数result作为下一次调用的实例参数可能会获得非常小的效率。如果函数结果在寄存器EAX中返回,并且下一次调用的实例指针在寄存器EAX中传递,则该流畅调用模式保存一条或两条指令,以将实例指针加载到EAX寄存器中以进行下一次调用。但就性能调整而言,这真的很小。
答案 3 :(得分:0)
您可以使用delegate
解决问题