C#中return ref a[0]无法修改原数组的原因及return ref正确用法咨询
问题根因
你当前代码修改不生效的核心问题是Main方法中接收返回值的变量没有声明为引用类型:
你写的var q = method(ref s);中,var会自动推断类型为int?,只会把method返回的a[0]的值拷贝给q,后续修改q是修改独立的副本,和原数组的a[0]没有关联。
正确修改方案
你需要显式将接收返回值的变量声明为ref类型,调整后的代码如下:
static void Main(string[] args) { int?[] s = new int?[5] { 1, 2, 3, 4, 5 }; // 显式用ref声明q为引用变量 ref int? q = ref method(ref s); q = 999; Console.WriteLine("s0 is " + s[0].ToString()); // 输出结果:s0 is 999,符合修改预期 } static ref int? method(ref int?[] a) { a[1] = 888; return ref a[0]; }
Debug无法查看&a地址的说明
C#作为托管语言,运行时会对托管对象进行地址重定位(GC回收、压缩堆时会移动对象地址),默认调试环境下不允许直接取托管引用的内存地址,属于正常现象。如果需要查看相关地址,可切换到反汇编视图或者关闭调试设置里的"属性评估和其他隐式函数调用"选项,常规开发场景下不需要手动获取托管引用的地址。
return ref使用核心规则
- 返回的引用必须符合生命周期安全要求:禁止返回方法内部栈上分配的局部变量的引用,方法退出后局部变量栈空间会被回收,悬挂引用会导致不可预期的错误
- 要修改返回的引用指向的内容,接收变量必须加
ref关键字,且调用方法时也要加ref关键字(该特性仅支持C# 7.0及以上版本) - 如果仅需要读取返回的引用值,不需要修改,可以不加
ref接收,此时获取的是值拷贝
内容的提问来源于stack exchange,提问作者Jianjie
相关产品推荐
相关产品推荐

