Jul*_*les 5 c# generics clr value-type
如果您有方法或类型Foo<T>,那么CLR可以为不同的T编译多个版本.我知道所有引用类型共享相同的版本.它对结构有什么作用?对于不同的结构,代码有时是共享的,还是从不共享的?例如,我可以想象代码是为所有相同大小的结构共享的.
我很感兴趣,因为我想知道以下示例:
interface IBar
{
void DoBar();
}
struct Baz : IBar
{
public void DoBar(){ ... }
}
struct Quux : IBar
{
public void DoBar(){ ... }
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我执行以下操作:
public void ExecuteBar<T>(T bar) where T:IBar
{
bar.DoBar();
}
ExecuteBar(new Baz());
ExecuteBar(new Quux());
Run Code Online (Sandbox Code Playgroud)
这是否会产生两个版本ExecuteBar,每一个直接(非虚拟的)直接打电话到Bar.DoBar()和Quux.DoBar()?或者是在运行时完成调度?
这个问题没有直接的答案,它很大程度上取决于您使用的抖动以及通用方法中存在什么样的代码。
起点是抖动确实为每个单独的值类型生成不同的方法。即使对于其他方面完全相同的结构也是如此。您可以使用调试器看到一些东西。使用“调试”+“Windows”+“反汇编”来查看生成的机器代码。单步进入一个方法,使用“调试+Windows+寄存器”窗口,EIP/RIP寄存器显示该方法在内存中的位置。
但是,像这样的通用方法仍然适合内联优化。对于perf来说非常重要,它让整个方法消失并且方法中的代码被注入到调用者方法中。在这种情况下,泛型方法之间的区别消失了。对于接口实现方法来说,通常不能指望会发生这种情况。但是,如果您将方法主体留空,则示例代码确实会发生这种情况。x86 和 x64 抖动的结果不同。
您只能通过查看生成的机器代码才能真正知道您得到了什么。请确保允许优化器完成其工作,“工具+选项”、“调试”、“常规”,取消选中“抑制 JIT 优化”复选框。当然,请确保您永远不会依赖这个问题的准确答案。此类实施细节如有更改,恕不另行通知。