C#引用传参时栈推送内容与ref返回值问题咨询
C#中引用传递时栈上的内容解析
先给你理清楚C#里值传递和ref传递的本质,结合你给的代码逐个拆解:
1. 普通传递引用类型(比如代码中的e1)
当你把e1作为参数传给method时,栈上推送的是**e1变量存储的引用值**——说白了就是托管堆上那个em实例的内存地址(32位系统是4字节,64位是8字节)。
- 这时候
method里的参数c是这个引用的副本,你修改c.i会影响堆上的原对象(因为副本和原引用指向同一个堆实例),但如果给c赋值new em(),只会改变c这个副本的引用值,完全不会影响Main里的e1变量。
2. ref传递引用类型(比如代码中的ref e2)
这时候栈上推送的是**Main方法栈帧里e2变量本身的内存地址**——也就是栈上存储e2那个引用的位置的地址。
method里的参数d相当于e2变量的别名,操作d就等于直接操作Main里的e2:- 修改
d.i:先通过d找到e2的引用值,再指向堆上的em实例,最终修改堆对象的字段,和普通传递的效果一致; - 给
d赋值new em():直接把新的引用值写到e2在栈上的位置,所以Main里的e2会直接指向新的堆实例,这是普通传递做不到的。
- 修改
3. ref返回对象时传递的内容
当你用ref返回一个对象(或者对象的字段)时,返回的是目标变量的内存地址:
- 如果返回的是
ref d(也就是ref e2),那返回的就是e2变量在栈上的地址,调用方用ref em result = ref p.method(...)接收后,修改result就等于修改e2; - 如果返回的是
ref d.i,那返回的是堆上em实例中i字段的地址,调用方修改result会直接改变堆对象的i值,不需要通过引用间接访问。
举个简单的代码片段辅助理解:
public ref em method(ref em d) { // 返回e2变量的地址 return ref d; } // 在Main里调用 ref em result = ref p.method(ref e2); result = new em(); // 这会直接修改Main里的e2
内容的提问来源于stack exchange,提问作者123
相关产品推荐
相关产品推荐

