C# 通过';值类型';按引用在堆栈上-内存占用
当我们通过引用传递已存储在堆栈上的值类型时,内存中会发生什么C# 通过';值类型';按引用在堆栈上-内存占用,c#,.net,memory,C#,.net,Memory,当我们通过引用传递已存储在堆栈上的值类型时,内存中会发生什么 必须在某个位置创建临时值/指针,以便在方法完成时更改原始值。有人能解释一下或者给我指出答案吗?记忆中有很多东西,但似乎没有一个能回答这个问题。ty听起来您正在寻找有关装箱和取消装箱的一些详细信息,这是用来描述将值类型视为引用类型的术语 有很多文章描述了这个过程,我会尝试找到一些合适的-。如果你有这样的方法: static void Increment(ref int value) { value = value + 1; }
必须在某个位置创建临时值/指针,以便在方法完成时更改原始值。有人能解释一下或者给我指出答案吗?记忆中有很多东西,但似乎没有一个能回答这个问题。ty听起来您正在寻找有关装箱和取消装箱的一些详细信息,这是用来描述将值类型视为引用类型的术语
有很多文章描述了这个过程,我会尝试找到一些合适的-。如果你有这样的方法:
static void Increment(ref int value)
{
value = value + 1;
}
int value = 5;
Increment(ref value);
这样称呼它:
static void Increment(ref int value)
{
value = value + 1;
}
int value = 5;
Increment(ref value);
然后发生的情况是,不是将值5推送到堆栈上,而是将变量value
的位置推送到堆栈上。即,值
的内容直接通过增量
更改,而不是在方法完成后更改
下面是方法和方法调用的IL:
.method private hidebysig static void Increment(int32& 'value') cil managed
{
.maxstack 8
L_0000: nop
L_0001: ldarg.0
L_0002: ldarg.0
L_0003: ldind.i4 // loads the value at the location of 'value'
L_0004: ldc.i4.1
L_0005: add
L_0006: stind.i4 // stores the result at the location of 'value'
L_0007: ret
}
.method private hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 9
.locals init ([0] int32 value) // <-- only one variable declared
L_0000: nop
L_0001: ldc.i4.5
L_0002: stloc.0
L_0003: ldloca.s 'value' // call Increment with the location of 'value'
L_0005: call void Program::Increment(int32&)
L_000a: ret
}
.method private隐藏静态无效增量(int32&“value”)cil管理
{
.maxstack 8
L_0000:没有
L_0001:ldarg.0
L_0002:ldarg.0
L_0003:ldind.i4//在“value”位置加载值
L_0004:ldc.i4.1
L_0005:添加
L_0006:stind.i4//将结果存储在“value”的位置
L_0007:ret
}
.method private隐藏静态void Main()cil managed
{
.入口点
.maxstack 9
.locals init([0]int32 value)//下面是对“为什么装箱和拆箱不好?”这提供了一些关于装箱/拆箱值类型的指针处理和性能影响的见解:谢谢-因此在堆栈上创建了指向堆栈上值位置的指针…酷!我希望调用堆栈能够准确显示内存中发生的情况。我可能需要一个内存分析器。如果您对正在发生的事情感兴趣在幕后,总是值得一看编译器生成的IL。你可以使用.NET Reflector来反汇编程序集。我确实经常使用Reflector,但还没有完全理解IL调用。我必须承认,出于某种原因,我没有想到在这里检查IL…再次感谢。