参数的高级用法
理解值传递与引用传递的区别
掌握 ref、out、params、可选参数、命名参数
能根据场景选择合适的参数方式
核心讲解
(1)值传递 vs 引用传递
值传递:默认方式,传递值的副本,方法内修改不影响原变量。值类型默认都是值传递。
引用传递:传递变量本身,方法内修改会影响原变量。用
ref关键字。
(2)ref 引用参数
方法定义和调用都要加
ref传入的变量必须先赋值
适合:交换变量、方法需要返回多个修改值
(3)out 输出参数
专门用来输出结果,方法内必须赋值
方法定义和调用都要加
out传入的变量可以不赋值
适合:方法有多个返回值的场景(现在更多用元组)
(4)params 参数数组
可变长度参数,方法调用时可以传任意个同类型参数
必须是形参列表最后一个
只能有一个 params 参数
适合:参数数量不确定的场景,比如求和、拼接
(5)可选参数
给参数设置默认值,调用时可以不传
默认值必须是常量
必须放在参数列表最后
适合:大部分情况用默认值的场景
(6)命名参数
调用时指定参数名传值
可以不按顺序传参
适合:参数多的方法,提高可读性
操作步骤
分别实现 ref、out、params、可选参数的方法
调用测试,观察结果
运行验证
代码示例
// 1. ref 引用参数:交换两个int
void Swap(ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}
int x = 10, y = 20;
Swap(ref x, ref y);
Console.WriteLine($"交换后:x={x}, y={y}");
// 2. out 输出参数:返回多个结果
bool Divide(int a, int b, out int result, out int remainder)
{
if (b == 0)
{
result = 0;
remainder = 0;
return false;
}
result = a / b;
remainder = a % b;
return true;
}
int res, rem;
bool ok = Divide(10, 3, out res, out rem);
Console.WriteLine($"\n除法:成功={ok},商={res},余={rem}");
// 3. params 可变参数:求和
int Sum(params int[] nums)
{
int total = 0;
foreach (int n in nums) total += n;
return total;
}
Console.WriteLine("\nparams求和:" + Sum(1, 2, 3));
Console.WriteLine("params求和:" + Sum(1, 2, 3, 4, 5));
// 4. 可选参数
void PrintInfo(string name, int age = 18, string city = "北京")
{
Console.WriteLine($"\n姓名:{name},年龄:{age},城市:{city}");
}
PrintInfo("张三"); // 用默认值
PrintInfo("李四", 25);
PrintInfo("王五", city: "上海"); // 命名参数,跳过中间参数
Console.ReadKey();
常见误区
ref 和 out 调用时不加关键字:定义和调用都必须加 ref/out,不然编译报错
out 参数不赋值:out 参数在方法内所有分支都必须赋值,不然报错
params 放中间:params 必须是最后一个参数,后面不能再有其他参数
可选参数顺序错:可选参数必须在必选参数后面
课后练习
用 ref 写一个方法,交换两个字符串变量
用 params 写一个方法,求任意个数字的最大值
写一个登录方法,用户名密码必选,记住我可选,默认 false
思考:ref 和 out 有什么区别?分别适合什么场景?

