这样做有什么意义吗?
public static void Write<T>(T value)
{
textWriter.Write(value.ToString());
}
......应该这样:
public static void Write(object value)
{
textWriter.Write(value.ToString());
}
抛开明显的空取消引用可能性,如果我在哪里用这种方法编写很多值类型,那么前者不会好得多,因为它将拥有它自己的write方法来调用,或者它只是根据生成的大量附加代码会使二进制文件膨胀吗?
这样的表现意味着可以忽略不计,但我很好奇,它比BCL中的每一个值类型都提供过载要紧凑得多,就像BCL中的大多数作者一样。
答案 0 :(得分:7)
据我所知,在两种情况下都会发生拳击。
后者很明显,因为该值已经装箱。
前者不那么明显,但是当在一个值类型上调用虚方法时,需要将其装箱以执行callvirt
。
编辑:我刚检查了发出的IL,并且在通用情况下没有明确的装箱。但是有些东西响了起来。
编辑2:我可能一直在使用接口混淆自己。有明显的拳击发生。
编辑3:如果值类型中未覆盖ToString()
,则会发生装箱。
我从ECMA-335第3部分第25页(仅注意到最后一个案例)得到这个:
如果 thisType 是值类型而且 thisType 没有实现方法 然后 ptr 被解除引用,装箱和 作为'this'指针传递给 方法的callvirt
最后一种情况只能发生在 方法是在
System.Object
上定义的,System.ValueType
,或System.Enum
和 没有被 thisType 覆盖。在这 最后一种情况,拳击会导致副本 原始物体, 然而,因为所有的方法System.Object
,System.ValueType
和。{System.Enum
不要修改状态 对象,这个事实不可能 检测
答案 1 :(得分:1)
考虑性能:
要点是:对于所有情况,没有一种完美的方法。
答案 2 :(得分:1)
是的,在大多数情况下会避免拳击。我不希望在大多数情况下会产生任何显着的性能差异。正如你自己所言,这可能是微不足道的。
我认为确实在可读性方面增加了一点负担。我怀疑大多数人在尝试理解通用方法时的认知负荷比他们采用object
的简单方法要多一些。谁将会使用这种方法,他们是否对泛型非常满意,以至于不会打扰他们?