C#常用参数传递方式汇总
作者:ceclar123
这篇文章主要介绍了C#传参机制:值传递、ref传递、out输出参数及params用法,深入解析引用类型与值类型的差异,详解ref与out参数的双向通信与单向输出机制,并探讨params参数的灵活传参应用,需要的朋友可以参考下
C#传参方式
| 传递方式 | 关键字 | 底层机制 | 值类型表现 | 引用类型表现 | 典型使用场景 |
|---|---|---|---|---|---|
| 默认值传递 | 无 | 复制一份数据(值类型复制内容,引用类型复制内存地址) | 方法内修改不影响外部 | 方法内修改属性会影响外部;但重新 new 不影响外部 | 绝大多数常规方法调用 |
| 引用传递 | ref | 传递变量的真实内存地址 | 方法内修改直接影响外部 | 方法内修改属性或重新 new 都直接影响外部 | 需要方法修改外部传入的变量(需提前初始化),必须加 ref |
| 输出参数 | out | 传递变量的真实内存地址 | 方法内必须重新赋值,外部才能获取新值 | 方法内必须重新赋值,外部才能获取新对象 | 方法需要返回多个结果(不要求传入前初始化),必须加 out |
| 只读引用 | in | 传递内存地址,但加上只读保护 | 方法内不可修改,避免大结构体复制开销 | 方法内不可修改引用,不可重新 new | 传递大型 struct 时的性能优化(必须初始化),可加 in,也可省略 |
| 可变参数 | params | 编译器自动将多个参数打包为数组 | 接收任意数量的同类型参数 | 接收任意数量的同类型参数 | 类似 string.Format() 的灵活传参 |
一、默认传递
引用类型传递的是地址的副本。这意味着你可以用这个副本去修改原对象的属性,但你不能把原对象“换掉”
public class Person { public string? Name { get; set; } }
public static void DefaultTest(Person p, int num)
{
p.Name = "李四"; // 修改属性:外部原对象会被修改!
num = 999; // 修改值类型:外部原变量不受影响
p = new Person { Name = "测试" }; // 重新赋值:外部原对象不受影响!
}
static void Main(string[] args)
{
Person p = new Person();
p.Name = "张三";
int num = 10;
Console.WriteLine($"修改前: name:{p.Name}, num:{num}");
DefaultTest(p, num);
Console.WriteLine($"修改后: name:{p.Name}, num:{num}");
}
二、ref引用传递(双向通信)
使用 ref 时,形参和实参指向完全相同的内存,任何操作都会同步到外部
public class Person { public string? Name { get; set; } }
public static void RefTest(ref Person p, ref int num)
{
num = 999; // 外部变量直接变成 999
p = new Person { Name = "李四" }; // 外部变量直接指向新对象
// p.Name = "李四"; // 修改属性:外部原对象会被修改!
}
static void Main(string[] args)
{
Person p = new Person();
p.Name = "张三";
int num = 10;
Console.WriteLine($"修改前: name:{p.Name}, num:{num}");
RefTest(ref p, ref num);
Console.WriteLine($"修改后: name:{p.Name}, num:{num}");
}
三、out输出参数(只出不进)
out 适合用来返回多个结果,传入前不需要初始化,但方法内部必须赋值
static void Main(string[] args)
{
int a;
if (int.TryParse("10", out a))
{
Console.WriteLine($"a:{a}");
}
int b;
if (int.TryParse("xyz", out b))
{
Console.WriteLine($"b:{b}");
}
else
{
Console.WriteLine($"b:{b}");
}
}
四、in只读传递(性能优化利器)
主要用于大型结构体(struct),避免复制带来的内存开销,同时保证数据安全
public struct Point
{
public int X; public int Y; public int Z;
}
public static void InTest(in Point point)
{
//point = new Point(); // ❌ 编译报错:不能修改
//point.X = 10; // ❌ 编译报错:不能修改属性
var copy = point; // ✅ 可以读取
}
五、params可变参数
必须放在参数列表的最后
static void Main(string[] args)
{
Console.WriteLine("{0},{1},{2},{3}", "hello", "world", "hello", "world");
}
以上就是C#常用参数传递方式汇总的详细内容,更多关于C#参数传递方式的资料请关注脚本之家其它相关文章!
