在“out”参数中传递值类型会导致变量被装箱吗?

时间:2011-01-26 16:29:49

标签: c# performance boxing unboxing

我在性能方面知道boxing and unboxing are relatively expensive。我想知道的是:

将值类型传递给方法的out参数会导致变量的装箱/取消装箱(从而导致性能下降)吗?编译器可以优化它吗?

  int number;
  bool result = Int32.TryParse(value, out number);

4 个答案:

答案 0 :(得分:18)

正如其他人所指出的,这里没有拳击。当您将变量作为对应于out或ref参数的参数传递时,您正在做的是为变量创建别名。您没有对变量的执行任何操作。您将两个变量表示为相同的存储位置。

仅当值类型的值转换为引用类型的值时才会发生限制,并且示例中没有任何类型的转换。引用类型当然必须是System.Object,System.ValueType,System.Enum或任何接口。通常很清楚;代码中有明确或隐式的转换。但是,可能会出现不太清楚的情况。例如,当调用struct的基类型的未重写的虚方法时,就会有拳击。 (还有一些奇怪的情况,某些类型的泛型类型约束会导致意外的拳击,但它们通常不会出现在实践中。)

答案 1 :(得分:6)

没有拳击,编译器使用ldloca.s指令将对局部变量的引用推送到堆栈上(http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldloca_s (VS.71)的.aspx)

.method private hidebysig static void Func() cil managed
{
    .maxstack 2
    .locals init (
        [0] int32 num,
        [1] bool flag)
    L_0000: nop 
    L_0001: ldstr "5"
    L_0006: ldloca.s num
    L_0008: call bool [mscorlib]System.Int32::TryParse(string, int32&)
    L_000d: stloc.1 
    L_000e: ret 
}

答案 2 :(得分:5)

不,没有拳击(必需/参与)。

当您执行Box变量时,对盒装实例的更改不会影响原始实例。但这正是out应该做的事情。

编译器'以某种方式'构造对原始变量的引用。

答案 3 :(得分:1)

没有拳击; out参数的作用是指定必须在TryParse方法中分配该编号。无论如何,它仍然被视为int,而不是object