一句话搞懂区别
- ref:传进去的时候必须有值,方法里可以改它,改完外面也能看到。
- out:传进去的时候不用有值(甚至不能有值),方法里必须给它赋值,赋完值外面就能用。
为什么需要它们?
C# 默认是“值传递”——你传一个变量进去,方法里改的是副本,外面原变量纹丝不动。
但有时候我们就是想让方法直接改外面的变量,或者一次返回多个结果,这时候就得靠 ref
和 out
。
ref:传进去有值,还能改
举个栗子
static void Main()
{int number = 10;Console.WriteLine($"调用前: {number}"); // 输出:10DoubleIt(ref number); // 注意:这里要加 ref!Console.WriteLine($"调用后: {number}"); // 输出:20
}static void DoubleIt(ref int value)
{value = value * 2; // 直接改外面的 number
}
关键点:
- 调用时:必须加
ref
- 传入前:变量必须初始化(比如
int number = 10;
) - 方法里:可以读也可以写
- 本质:相当于传了个“地址”,方法直接操作原变量
out:专门用来“输出”结果
举个栗子
static void Main()
{// 注意:这里没给 result 赋值!甚至不能赋(赋了也白赋)bool success = TryParseInt("123", out int result);if (success){Console.WriteLine($"解析成功: {result}"); // 输出:123}
}// 模拟 int.TryParse
static bool TryParseInt(string input, out int output)
{// out 参数在方法里必须赋值!否则编译报错if (int.TryParse(input, out output)){return true;}else{output = 0; // 必须赋值,哪怕没用return false;}
}
关键点:
- 调用时:必须加
out
- 传入前:不需要初始化(写了也白写,编译器会忽略)
- 方法里:必须至少赋值一次(否则编译不过)
- 用途:常用于“尝试操作”并返回额外结果(比如解析、查找等)
对比总结(表格更清楚)
特性 | ref | out |
---|---|---|
调用前是否要初始化 | ✅必须 | ❌不需要(甚至不能有值) |
方法内是否必须赋值 | ❌不强制(但通常会改) | ✅必须至少赋一次 |
主要用途 | 修改已有变量 | 返回额外结果(多返回值) |
调用时写法 | Method(ref x) |
Method(out x) |
实际应用场景
ref 常见用法:
- 高性能场景(避免复制大结构体)
- 需要修改传入的值(比如交换两个数)
void Swap(ref int a, ref int b)
{int temp = a;a = b;b = temp;
}
out 常见用法:
-
TryXXX
模式(如int.TryParse
,Dictionary.TryGetValue
) - 一个方法返回多个结果
void GetCoordinates(out int x, out int y)
{x = 100;y = 200;
}
小贴士
- C# 7.0+ 支持在调用时直接声明 out 变量,不用提前定义:
if (int.TryParse("456", out var number))
{Console.WriteLine(number); // 直接用
}
- ref 和 out 不能重载:
Method(ref int)
和Method(out int)
算同一个方法,会冲突。 - 别乱用:大多数情况用返回值或元组(
return (a, b);
)更清晰。ref/out 适合特定场景。
最后一句话记住:
ref 是“带值进去,还能改出来”;out 是“空手进去,必须带值出来”。
搞定!