当前位置:首页 > 技能相关 > C#与C++ > 正文内容

C#进阶 值传递和引用传递

admin1个月前 (01-26)C#与C++900 修订时间:2026-01-26 15:01:55

在 C# 中,传递参数的方式取决于参数的类型,而不是传递方式的关键字(虽然 ref/out/in可以改变行为)。理解值类型和引用类型的内存布局是掌握参数传递的关键。

1. 核心概念

值类型

- 结构体(`struct`)、枚举(`enum`)、基本类型(`int`, `bool`, `double` 等)

- 直接存储数据

- 分配在栈上(除非被装箱或作为类的字段)

引用类型

- 类(`class`)、接口(`interface`)、委托(`delegate`)、数组(`array`)

- 存储对数据的引用(内存地址)

- 实例分配在堆上

2. 参数传递的四种方式

方式 1:默认传递(按值传递)

// 值类型:传递副本
void ModifyValue(int x)
{
    x = 100;  // 只修改副本
}

// 引用类型:传递引用的副本
void ModifyArray(int[] arr)
{
    arr[0] = 100;        // 修改原始对象的内容 ✓
    arr = new int[10];   // 只修改局部副本的引用 ✗
}

// 使用
int num = 10;
ModifyValue(num);        // num 仍然是 10

int[] array = { 1, 2, 3 };
ModifyArray(array);      // array[0] 变为 100,但 array 仍指向原数组

方式 2:ref 传递(按引用传递)

// 传递变量本身的引用
void ModifyWithRef(ref int x, ref int[] arr)
{
    x = 100;             // 修改原始变量
    arr = new int[10];   // 修改原始引用
}

// 使用
int num = 10;
int[] array = { 1, 2, 3 };
ModifyWithRef(ref num, ref array);
// num = 100, array 指向新数组

方式 3:out 传递(输出参数)

// 用于输出结果,调用前不需要初始化
bool TryParse(string input, out int result)
{
    if (int.TryParse(input, out int temp))
    {
        result = temp;
        return true;
    }
    result = 0;
    return false;
}

// 使用(C# 7.0+ 可以在调用时声明变量)
TryParse("123", out int value);

方式 4:in 传递(只读引用)

// 传递只读引用,提高大值类型的性能
double CalculateDistance(in Vector3D v1, in Vector3D v2)
{
    // v1.X = 10;  // 错误:无法修改只读变量
    return Math.Sqrt(v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z);
}
readonly struct Vector3D
{
    public double X { get; }
    public double Y { get; }
    public double Z { get; }
}

3. 详细对比

特性
默认(值传递)ref outin
是否需要初始化
方法内能否读取否(必须赋值)
方法内能否修改修改副本修改原始必须修改原始不能修改
值类型性能复制整个值高效(传地址)高效(传地址)高效(传地址)
调用时语法Method(arg)Method(ref arg)Method(out arg)Method(in arg)

4.最佳实践

1. 避免修改输入参数(除非使用 ref/out 明确意图)

2. 大值类型使用 in 避免复制开销

3. out 用于返回多个值,替代 Tuple

4. 谨慎使用ref,会降低代码可读性

5. readonly struct 与 in参数是性能优化组合

 您阅读本篇文章共花了: 

免责声明
本站内容均为博客主本人日常使用记录的存档,如侵犯你的权益请联系:lifei@zaiheze.com 546262132@qq.com 沟通删除事宜。本站仅带访问端口形式使用,已杜绝搜索引擎爬取。

扫描二维码推送至手机访问。

版权声明:本文由LIFEI - blog发布,如需转载请注明出处。

本文链接:http://lifeiai.com/index.php?id=464

分享给朋友:

相关文章

Web API的创建3年前 (2022-11-07)
C# 第一篇 踏上征程 3年前 (2022-11-14)
C# 第二篇 基础语法3年前 (2022-11-14)
C# 第三篇 流程控制3年前 (2022-11-15)
C# 第四篇 数组定义3年前 (2022-11-15)

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。