You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# ref返回值两种接收方式的差异及底层原理疑问

C# ref返回值的底层运行机制解析

示例代码

FindAuthor方法

public ref string FindAuthor(int number, string[] names)
{
    if (names.Length > 0)
        return ref names[number];   
    throw new IndexOutOfRangeException($"{nameof(number)} not found.");
}

主方法调用

//main method
string[] authors = { "Mahesh Chand", "Mike Gold", "Dave McCarter", 
                "Allen O'neill", "Raj Kumar" };

//first variation
string author4 = new Program().FindAuthor(3, authors);
Console.WriteLine("Original author:{0}", author4);
author4 = "Chris Sells";
Console.WriteLine("Replaced author:{0}", authors[3]);

//secondvariation
ref string author4 = ref new Program().FindAuthor(3, authors);
Console.WriteLine("Original author:{0}", author4);
author4 = "Chris Sells";
Console.WriteLine("Replaced author:{0}", authors[3]);

问题核心

FindAuthor方法始终以ref方式返回值,但用普通string author4接收并修改时,原数组无变化;用ref string author4接收修改时,数组会同步改变。为何会有这种差异?

底层运行机制解析

  • ref返回值的本质:ref返回的不是变量的值,而是变量在内存中的地址引用。数组元素在内存中连续存储,names[number]指向的是数组对应索引位置的内存地址。

  • 普通接收方式的行为:当用普通字符串变量接收ref返回值时,C#会自动解引用该内存地址,把地址里存储的字符串引用拷贝到author4自己的内存空间。此时author4和数组元素是两个独立变量,修改author4只是让它指向新的字符串对象,完全不会影响原数组元素的内存内容。

  • ref接收方式的行为:用ref关键字接收时,author4直接绑定到原数组元素的内存地址,相当于原元素的"别名"。对author4的赋值操作,本质是直接修改该内存地址里存储的字符串引用,因此会同步改变原数组。

  • 字符串类型的补充说明:虽然字符串是引用类型,但这里的核心差异不在字符串本身——哪怕是值类型数组(比如int[]),普通接收和ref接收也会产生同样的结果:普通接收拷贝值,ref接收绑定内存地址,修改会影响原数组。

内容的提问来源于stack exchange,提问作者Eric Movsessian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 10:07:25