Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过';值类型';按引用在堆栈上-内存占用_C#_.net_Memory - Fatal编程技术网

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…再次感谢。