拳击,过去的事情?

Joh*_*ren 6 .net c#

这样做有什么意义吗?

public static void Write<T>(T value)
{
    textWriter.Write(value.ToString());
}
Run Code Online (Sandbox Code Playgroud)

......应该这样:

public static void Write(object value)
{
    textWriter.Write(value.ToString());
}
Run Code Online (Sandbox Code Playgroud)

抛开明显的空取消引用可能性,如果我在哪里使用这种方法编写很多值类型,那么前者不会好得多,因为它将拥有自己的write方法来调用,或者它会臃肿二进制在生成大量额外代码方面?

这种事情的性能含义可以忽略不计,但我很好奇,它比为BCL中的每一个值类型提供重载要紧凑得多,就像BCL中的大多数编写者一样.

lep*_*pie 7

从我的理解,在两种情况下拳击发生.

后者很明显,因为价值已经装箱.

前者不那么明显,但是当一个虚拟方法在一个valuetype上调用时,它需要被装箱以执行callvirt.

编辑:我刚检查了发射的IL,并且在通用情况下没有明确的装箱.虽然有东西响了.

编辑2:我可能一直在使用接口混淆自己.有明显的拳击发生.

编辑3:如果ToString()未在值类型中覆盖,则确实发生了拳击.

我从ECMA-335第3部分第25页得到这个(仅注意到最后一个案例):

如果thisType是一个值类型而 thisType没有实现方法,则ptr被解除引用,装箱,并作为'this'指针传递给方法的callvirt

当方法定义只能出现最后这种情况下System.Object, System.ValueTypeSystem.Enum,而不是由覆盖thisType.在后一种情况下,拳击导致制作原始对象的副本,但是因为所有的方法 System.Object,System.ValueTypeSystem.Enum不修改对象的状态,这个事实不能被检测到.

编辑4: 这是一个关于SO的类似问题.