C# 是否在“中传递值类型”;“出去”;参数是否导致变量被装箱?

C# 是否在“中传递值类型”;“出去”;参数是否导致变量被装箱?,c#,performance,boxing,unboxing,C#,Performance,Boxing,Unboxing,我知道在性能方面。我想知道的是: 将值类型传递给方法的out参数是否会导致变量装箱/拆箱(从而影响性能)?编译器可以优化它吗 int number; bool result = Int32.TryParse(value, out number); 不,没有装箱(要求/涉及) 当您装箱变量时,对装箱实例的更改不会影响原始实例。但这正是out应该做的 编译器以某种方式构造对原始变量的引用 没有拳击;out参数所做的是指定必须在TryParse方法中分配数字。尽管如此,它仍然被视为int,而

我知道在性能方面。我想知道的是:

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

  int number;
  bool result = Int32.TryParse(value, out number);
不,没有装箱(要求/涉及)

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


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

没有拳击;
out
参数所做的是指定必须在
TryParse
方法中分配数字。尽管如此,它仍然被视为
int
,而不是
对象

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


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


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

查找过早优化。解析一个整数(一般来说是解析)比简单的装箱操作要昂贵得多。@Dykam:True。不过,我只是以
TryParse
为例。谢谢你的回答。还有表演热播吗?它与装箱/拆箱、传递引用类型或传递值类型的命中率相比如何?@Justin:对于任何性能问题,最好的建议是:试试看,你会发现的。您可能会发现,通常通过引用传递变量的成本与通过引用传递引用到引用类型实例的成本相同,这与传递IntPtr size的值类型的成本相同。请记住,如果有可用的寄存器,指针大小的参数传递会被抖动严重优化。谢谢你的回答。你知道是否还有表演热播吗?它与装箱/拆箱的命中率或传递普通参数相比如何?@Justin,开销将取决于环境(字段或本地变量),但对于本地
out
来说,开销可能是最快的。你必须衡量你的处境。但这充其量只是一个微观优化,没有真正的替代方案。
.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 
}