☰
C# 中 ref 与 out 参数详解:区别、常见错误与最佳实践
2026/10/27 1:00:43 网站建设 项目流程

在 C# 的方法参数传递中,ref和out都可以让方法把修改结果带回调用方,但两者的使用规则并不相同。本文通过一个分数调整的示例,说明ref与out的差异、常见编译错误,以及值参数、引用参数和输出参数之间的本质区别。

一、问题引入:同时使用 ref 和 out

先看下面这段代码,它同时使用了ref和out参数:

using System; class Program { static void Main() { Program obj = new Program(); int score = 55; // 原始分数 int refscore, outscore; // 声明两个变量 obj.ChangeScore(score, ref refscore, out outscore); Console.WriteLine("您原来的分数是{0},调整后的分数为{1},加平时表现分后{2}", score, refscore, outscore); Console.ReadKey(); } private void ChangeScore(int score, ref int refscore, out int outscore) { if (score > 50 && score < 60) { refscore = 60; } if (refscore > 60) { outscore = refscore + 5; } } }

二、编译错误分析

以上代码在编译时会报出两个错误:

  • 使用了未赋值的局部变量 refscore:代码只声明了refscore,却没有在调用前给它赋值。作为ref参数,实参在传入方法之前必须已经初始化。
  • 控制离开方法之前必须对 out 参数 outscore 赋值:out参数要求被调用方法在返回前必须为其赋值。示例中只有满足if条件时才给outscore赋值,不满足条件的分支没有赋值,因此编译器报错。

三、修正后的代码

针对上述两个问题,分别给refscore赋初值,并为outscore补上else分支,代码即可正常编译:

using System; class Program { static void Main() { Program obj = new Program(); int score = 55; // 原始分数 int refscore = 0, outscore; // ref 参数必须先赋初值 obj.ChangeScore(score, ref refscore, out outscore); Console.WriteLine("您原来的分数是{0},调整后的分数为{1},加平时表现分后{2}", score, refscore, outscore); Console.ReadKey(); } private void ChangeScore(int score, ref int refscore, out int outscore) { if (score > 50 && score < 60) { refscore = 60; } if (refscore > 60) { outscore = refscore + 5; } else { outscore = refscore; // 保证 out 参数在所有路径上都被赋值 } } }

四、值参数、引用参数与输出参数的区别

1. 值参数

值参数中实参的值不会随形参的变更而变更。实参传递给形参时,栈中会为形参另外分配一部分空间,因此形参与实参互不影响。

2. 引用参数与输出参数

引用参数和输出参数中,实参的值会随形参的变更而变更。实参在栈中分配空间,传递给形参时传递的是地址(即指针),因此形参变更时实参也会随之变更。

补充说明:形参是在定义函数时指定的参数,在未发生函数调用时并不占用内存的存储单元。只有在函数调用发生时,形参才被分配内存单元;调用结束后,形参所占的内存单元被释放。调用时会将实参的值赋给形参。

五、ref 与 out 的区别

  1. 使用ref与out参数时,方法定义中的参数和调用处的实参都需要加上对应的ref或out关键字。
  2. 使用ref参数与out参数得到的结果是一样的,区别在于:ref要求在调用前给实参赋初值;out在调用前不需要给实参赋初值,但必须在方法体内完成初始化。

六、使用建议

  • 需要方法读取并修改已有变量时,使用ref,并确保调用前变量已初始化。
  • 需要方法返回多个结果、且调用方不关心传入值时,使用out,并保证方法内所有执行路径都为其赋值。
  • 如果只是返回单个结果,优先使用返回值而不是out,代码可读性更好。
  • 在 C# 7.0 及以上版本中,可以使用out var在调用处直接声明变量,减少提前声明的冗余代码。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询