代码之家  ›  专栏  ›  技术社区  ›  John Leidegren

拳击,过去的事?

  •  6
  • John Leidegren  · 技术社区  · 14 年前

    public static void Write<T>(T value)
    {
        textWriter.Write(value.ToString());
    }
    

    …应该是这样的:

    public static void Write(object value)
    {
        textWriter.Write(value.ToString());
    }
    

    抛开明显的空引用的可能性不谈,如果我在哪里使用这个方法编写大量的值类型,那么前者不是更好吗,因为它将有自己版本的write方法来调用,或者它只是会在生成大量额外代码的情况下膨胀二进制文件?

    3 回复  |  直到 14 年前
        1
  •  7
  •   Community CDub    7 年前

    据我所知,在这两种情况下拳击都会发生。

    后者是显而易见的,因为值已经装箱。

    callvirt

    编辑: 我刚刚检查了发出的IL,在一般情况下没有显式装箱。不过,还是有一些事情发生了。

    编辑2:

    ToString() 未在值类型中重写。

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

    如果 这种类型 是值类型,并且 不实现方法 ptr公司 作为此指针传递给 方法的callvirt

    最后一种情况只能发生在 System.Object , System.ValueType System.Enum 和 未被覆盖 这种类型 但是由于所有的方法 System.Object System.ValueType ,和 System.Enum 不要修改的状态 对象,这个事实不可能 检测。

    编辑4: Here is a similar question on SO .

        2
  •  1
  •   Jon Skeet    14 年前

    我认为 object . 谁会使用这个方法,他们对泛型是否足够满意,这样就不会困扰他们了?

        3
  •  1
  •   peterchen    14 年前
    • 虚拟调用可能需要装箱(正如leppie已经说过的)
    • 泛型在源代码上更紧凑,但在JIT'ed代码中却没有

    • 泛型稍微减小了二进制大小。JIT时间和代码位置保持不变,因为无论如何只会JIT所需的重载
    • 如果方法不像示例中那样简单化,装箱解决方案将涉及更少的JIT调用并减少代码大小(从而也提高了局部性)。这是一种累积效应,除非在极端情况下,否则很难衡量。