在C#中,引用类型如class实例存储在托管堆上,变量本身保存的是对象的内存地址。当把引用类型作为参数传入方法时,默认是按值传递,也就是复制了一份引用地址;而使用ref关键字则是按引用传递,形参与实参共享同一个引用变量。这两种方式在方法内对参数的操作会产生明显不同的结果。

按值传递引用类型
下面的例子演示了默认按值传递时,方法内修改对象字段会影响原对象,但重新给参数赋值不会改变调用方的变量。
using System;
class Person
{
public string Name;
}
class Program
{
static void ChangeByValue(Person p)
{
p.Name = "Tom"; // 修改字段,原对象受影响
p = new Person(); // 重新赋值,只改变副本
p.Name = "Jerry";
}
static void Main()
{
Person a = new Person();
a.Name = "Alice";
ChangeByValue(a);
Console.WriteLine(a.Name); // 输出 Tom
}
}
按引用传递引用类型
使用ref关键字后,形参成为实参的别名。方法内对参数本身的赋值会直接反映到调用方。
using System;
class Person
{
public string Name;
}
class Program
{
static void ChangeByRef(ref Person p)
{
p = new Person(); // 重新赋值,调用方变量也改变
p.Name = "Jerry";
}
static void Main()
{
Person a = new Person();
a.Name = "Alice";
ChangeByRef(ref a);
Console.WriteLine(a.Name); // 输出 Jerry
}
}
核心差异对比
| 传递方式 | 形参本质 | 修改对象字段 | 重新赋值参数 |
|---|---|---|---|
| 按值传递 | 引用副本 | 影响原对象 | 不影响调用方 |
| 按引用传递 | 引用别名 | 影响原对象 | 影响调用方 |
常见误区
有人误以为引用类型总是按引用传递,其实C#默认的parameter passing对于引用类型也是按值传递。只有显式写上ref或out才是真正的按引用传递。理解这一点有助于在写工具方法时正确选择参数修饰符。
使用建议
- 如果只是读取或修改对象状态,按值传递即可。
- 若需要方法内部创建新对象并替换调用方变量,使用ref。
- out适用于必须返回新引用且调用前无需初始化的场景。
记住:引用类型按值传递,传的是地址的副本;按引用传递,传的是地址变量的别名。
C#引用类型按值传递_按引用传递修改时间:2026-07-27 04:18:16