C# ref 和 out 的使用详解
总目录
前言
在 C# 编程中,ref 和 out 是两个非常重要的关键字,它们都用于方法参数的传递,但用途和行为却有所不同。今天,我们就来深入探讨一下这两个关键字的用法和区别,让你在编程中能够得心应手地使用它们。
一、什么是 ref 和 out?
在 C# 中,方法的参数默认是通过值传递的,这意味着方法内部对参数的修改不会影响到外部的变量。但有时候,我们希望方法能够修改外部变量的值,或者需要返回多个值。这时候,ref 和 out 就派上用场了。
- ref:表示引用传递。它允许方法修改传入的变量的值,并且这些修改会反映到外部变量上。
- out:也表示引用传递,但它主要用于返回多个值。与 ref 不同的是,out 参数在传入方法之前不需要初始化。
二、传值赋值和传址赋值
- 传值赋值:赋值运算符操作的是值类型数据或字符串
- 传址/引用赋值:赋值运算符操作的是引用类型数据,除字符串
class User
{public string Id { get; set; }public string Name { get; set; }public string Sex { get; set; }
}class Program
{static void Main(){// 值类型 和 string int num = 10;string text = "hello";ChangeValue(num,text);Console.WriteLine(num); // 输出10,原值纹丝不动!Console.WriteLine(text); // 输出hello,原值纹丝不动!// 引用类型 除 stringUser user = new User() { Id = "1", Name = "鲲籽鲤", Sex = "男" };UpdateUser(user);Console.WriteLine($"User.Id={user.Id},User.Name={user.Name}");// 输出:User.Id=2,User.Name=鲤籽鲲}static void ChangeValue(int x,string str){x = 100;str = "ni hao";}static void UpdateUser(User user){user.Id = "2";user.Name = "鲤籽鲲";}
}
通过以上案例可知:
- 在对值类型以及字符串进行赋值的时候,是将值进行的复制。
- 在对引用类型(除字符串)进行赋值的时候,是将数据内容的索引或地址进行的复制
二、ref 的使用
1. 基本用法
ref 参数必须在调用方法之前初始化。我们来看一个简单的例子:
public void IncreaseValue(ref int value)
{value += 10;
}// 调用示例
int myNumber = 5;
IncreaseValue(ref myNumber);
Console.WriteLine(myNumber); // 输出:15
在这个例子中,myNumber的值被方法IncreaseValue增加到了15。因为ref传递的是引用,所以对value的任何修改都会反映到myNumber上。
public void Swap(ref int a, ref int b)
{int temp = a;a = b;b = temp;
}int x = 10;
int y = 20;
Swap(ref x, ref y);
Console.WriteLine($"x: {x}, y: {y}"); // 输出:x: 20, y: 10
在这个例子中,Swap 方法通过 ref 参数交换了两个整数的值。调用方法时,我们需要在参数前加上 ref 关键字,并且变量 x 和 y 必须在调用之前初始化。
2. 注意事项
- 必须初始化:ref 参数在传入方法之前必须被赋值,否则会报编译错误。
- 修改外部变量:ref 参数允许方法修改外部变量的值,这可能会导致意外的副作用,所以使用时要小心。
三、out 的使用
1. 基本用法
out 参数主要用于返回多个值,它在传入方法之前不需要初始化,但方法内部必须为 out 参数赋值。来看一个例子:
public void GetMinMax(int[] numbers, out int min, out int max)
{min = numbers[0];max = numbers[0];foreach (int num in numbers){if (num < min) min = num;if (num > max) max = num;}
}int[] numbers = { 5, 2, 9, 1, 7 };
int min, max;
GetMinMax(numbers, out min, out max);
Console.WriteLine($"Min: {min}, Max: {max}"); // 输出:Min: 1, Max: 9
在这个例子中,GetMinMax 方法通过 out 参数返回了数组中的最小值和最大值。调用方法时,我们只需要声明变量 min 和 max,而不需要在调用之前初始化它们。
public void Divide(int dividend, int divisor, out int quotient, out int remainder)
{quotient = dividend / divisor;remainder = dividend % divisor;
}// 调用示例
Divide(10, 3, out int quotient, out int remainder);
Console.WriteLine($"Quotient: {quotient}, Remainder: {remainder}");
// 输出:Quotient: 3, Remainder: 1
Divide方法不仅计算了商(quotient),还计算了余数(remainder)。注意,我们在调用时声明了两个out变量,并且在方法内部都进行了赋值。
2. 注意事项
- 无需初始化:out 参数在传入方法之前不需要初始化,方法内部必须为 out 参数赋值。
- 返回多个值:out 参数非常适合用于返回多个值,但过多的 out 参数可能会使代码变得复杂,可读性降低。
四、ref 和 out 的区别
| 特性 | ref | out |
|---|---|---|
| 初始化要求 | 必须在传入方法之前初始化 | 不需要初始化,方法内部必须赋值 |
| 方法内赋值 | 可改可不改 方法内可以不修改值(但通常建议修改) | 必须赋值 |
| 用途 | 修改外部变量的值 | 返回多个值 |
| 调用方式 | 调用时和方法定义时都需要加 ref | 调用时和方法定义时都需要加 out |
| 语义 | 输入输出 | 纯输出 |
- 使用ref可以让方法读取和修改传入参数的值,但需要先初始化。
- 使用out可以在方法中返回额外的结果,而不需要提前初始化参数,但方法内必须对out参数赋值。
- out 更侧重输出,即是说将传进方法的参数,自行在内部赋值,然后给到外部使用,正因它是必须在内部赋值,所以它不在乎该变量是否有初始值
- ref 更侧重修改,即是说传进方法的参数本身就有值,在方法内部对变量值进行修改,它只是对变量的值进行修改,因此他要求变量必须有初始值
五、应用场景
1. TryParse模式(经典out用法):
if(int.TryParse("123", out var result))
{// 安全使用result
}
2. 大结构体优化(ref高级用法):
void 处理大结构(ref BigStruct data)
{// 避免值类型复制开销
}
3. Swapper工具(ref炫技):
void Swap(ref int a, ref int b)
{(a, b) = (b, a);
}
五、in 关键字(补充)
从 C# 7.2 开始,引入了 in 关键字。它用于传递只读引用,方法内部不能修改传入的参数值。这在传递大型结构体时可以提高性能,同时保证数据的安全性。
public void Print(in Person person)
{Console.WriteLine(person.Name);// person.Name = "New Name"; // 编译错误,不能修改
}
六、注意事项
- 用out时代替多返回值更优雅
- 异步方法中禁止使用
- 属性不能作为参数传递(编译直接报错)
- 重载方法时ref和out算不同签名
- ref适用:游戏角色属性修改、实时数据更新
- out适用:数据解析、状态检测返回多值
结语
回到目录页:C#/.NET 知识汇总
希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。
相关文章:
C# ref 和 out 的使用详解
总目录 前言 在 C# 编程中,ref 和 out 是两个非常重要的关键字,它们都用于方法参数的传递,但用途和行为却有所不同。今天,我们就来深入探讨一下这两个关键字的用法和区别,让你在编程中能够得心应手地使用它们。 一、什…...
Ubuntu 24.04.1 LTS 本地部署 DeepSeek 私有化知识库
文章目录 前言工具介绍与作用工具的关联与协同工作必要性分析 1、DeepSeek 简介1.1、DeepSeek-R1 硬件要求 2、Linux 环境说明2.1、最小部署(Ollama DeepSeek)2.1.1、扩展(非必须) - Ollama 后台运行、开机自启: 2.2、…...
用 WOW.js 和 animate.css 实现动画效果
用 wow.js 就可以实现动画效果,但由于里面的动画样式太少,一般还会引入 animated.css 第一步:下载 选择合适的包管理器下载对应的内容 pnpm i wow.js animated.css --save 第二步:引入 在main.js中加入: import …...
1-知识图谱-概述和介绍
知识图谱:浙江大学教授 陈华军 知识图谱 1课时 http://openkg.cn/datasets-type/ 知识图谱的价值 知识图谱是有什么用? 语义搜索 问答系统 QA问答对知识图谱:结构化图 辅助推荐系统 大数据分析系统 自然语言理解 辅助视觉理解 例…...
flink jobgraph详细介绍
一、Flink JobGraph 的核心概念 JobGraph 是 Flink 作业的核心执行计划,它描述了作业的任务拓扑结构和数据流关系。JobGraph 由以下几部分组成: 顶点(Vertex) 每个顶点代表一个任务(Task),例如…...
使用nginx+rtmp+ffmpeg实现桌面直播
使用nginxrtmpffmpeg实现桌面直播 流媒体服务器搭建 docker run docker镜像基于添加了rtmp模块的nginx,和ffmpeg docker pull alfg/nginx-rtmp docker run -d -p 1935:1935 -p 8080:80 --namenginx-rtmp alfg/nginx-rtmprtmp模块说明 进入容器内部查看 docker…...
每日一题——将数字字符串转化为IP地址
将数字字符串转化为IP地址 题目描述解题思路回溯法步骤分解 代码实现全局变量有效性验证函数回溯函数主函数完整代码 复杂度分析关键点说明总结 这题难度还挺大的,整体上实现并不容易。建议参考视频 和https://programmercarl.com/0093.%E5%A4%8D%E5%8E%9FIP%E5%9C%…...
机器学习数学基础:25.随机变量分布详解
一、随机变量与分布函数的基本概念 (一)什么是随机变量? 在概率论领域,随机变量是将随机试验的结果进行数值化的关键概念。它就像一座桥梁,把抽象的随机事件和具体的数学分析连接起来。 举例来说,在一个…...
香港电讯与Zenlayer达成战略合作,拓展全球互联生态圈
作为主要国际金融与贸易中心,香港一直是连系中国内地及全球市场的重要门户。香港电讯作为本地领先的综合电讯服务提供商,拥有广泛的网络资源和深厚的技术专长,一直支持国内企业“走出去”和外资企业“走进来”。而旗下由PCCW Global营运的Con…...
MySQL-事务隔离级别
事务有四大特性(ACID):原子性,一致性,隔离性和持久性。隔离性一般在事务并发的时候需要保证事务的隔离性,事务并发会出现很多问题,包括脏写,脏读,不可重复读,…...
【Python学习 / 6】面向对象编程(OOP)
文章目录 ⭐前言⭐一、类和对象:面向对象编程基础1. 类(Class)类的组成:例子:定义一个简单的 Dog 类代码解析: 2. 对象(Object)对象的创建: 3. 三大特性:封装…...
Ollama DeepSeek + AnythingLLM 实现本地私有AI知识库
Ollama DeepSeek AnythingLLM 实现本地私有AI知识库 本地部署DeepSeek-r1下载安装AnythingLLMAnythingLLM 配置LLM首选项Embedder首选项向量数据库工作区其他配置 AnythingLLM Workspace使用上传知识词嵌入知识检索 本文主要介绍了如何使用AnythingLLM结合Ollama部署的DeepSee…...
个人博客测试报告
一、项目背景 个人博客系统采用前后端分离的方法来实现,同时使用了数据库来存储相关的数据,同时将其部署到云服务器上。前端主要有四个页面构成:登录页、列表页、详情页以及编辑页,以上模拟实现了最简单的个人博客系统。其结合后…...
嵌入式八股文(四)计算机网络篇
第一章 基础概念 1. 服务 指网络中各层为紧邻的上层提供的功能调用,是垂直的。包括面向连接服务、无连接服务、可靠服务、不可靠服务。 2. 协议 是计算机⽹络相互通信的对等层实体之间交换信息时必须遵守的规则或约定的集合。⽹络协议的三个基本要素:语法、…...
基于Electron+Vue3创建桌面应用
Electron 是一个开源框架,基于 Chromium 和 Node.js,用于开发跨平台桌面应用程序。它允许开发者使用 HTML、CSS 和 JavaScript 等 Web 技术构建原生桌面应用,支持 Windows、macOS 和 Linux。Electron 以其开发便捷性、强大的功能和丰富的生态系统而广泛应用于工具类应用、媒…...
建立稳定分析模式的模式语言01
Haitham Hamza 等 著,wnb 译 摘要 一般认为,软件分析模式在减少开销和缩短软件产品生命周期等方面会起到重要的作用。然而,分析模式的巨大潜能还未被充分发掘。缺乏稳定性是当前分析模式存在的主要问题。多数情况下,为特定问题建…...
【C++游戏开发-五子棋】
使用C开发五子棋游戏的详细实现方案,涵盖核心逻辑、界面设计和AI对战功能: 1. 项目结构 FiveChess/ ├── include/ │ ├── Board.h // 棋盘类 │ ├── Player.h // 玩家类 │ ├── AI.h // AI类 │ └── Game.h // 游戏主逻辑 ├── src/ …...
ubuntu20动态修改ip,springboot中yaml的内容的读取,修改,写入
文章目录 前言引入包yaml原始内容操作目标具体代码执行查看结果总结: 前言 之前有个需求,动态修改ubuntu20的ip,看了下: 本质上是修改01-netcfg.yaml文件,然后执行netplan apply就可以了。 所以,需求就变成了 如何对ya…...
tailwindcss学习02
vue中接入tailwindcss 使用cmd不要使用powershell npm create vitelatest stu02 -- --template vue cd stu02npm install --registry http://registry.npm.taobao.org npm install -D tailwindcss3.4.17 postcss autoprefixer --registry http://registry.npm.taobao.org npx t…...
千峰React:脚手架准备+JSX基础
组件化->封装性 React提供函数组件实现组件化 React和传统JS的区别就是JS需要手动管理DOM操作,React: 采用组件化开发,通过虚拟DOM提升性能。 MVC 是一种软件设计模式,全称为 Model-View-Controller(模型-视图-控制器&#x…...
二维码修复神器QrazyBox:拯救损坏二维码的终极指南
二维码修复神器QrazyBox:拯救损坏二维码的终极指南 【免费下载链接】qrazybox QR Code Analysis and Recovery Toolkit 项目地址: https://gitcode.com/gh_mirrors/qr/qrazybox 核心关键词:二维码修复工具、QR码恢复软件、损坏二维码解码、在线二…...
微信聊天记录永久保存指南:用免费开源工具完整备份你的数字记忆
微信聊天记录永久保存指南:用免费开源工具完整备份你的数字记忆 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否曾因为手机丢失、误删聊天记录而懊恼不…...
开源职业发展AI技能包Career-Ops:四阶段引擎驱动,告别AI废话
1. 项目概述与核心价值如果你正在用 Claude Code、Cursor 这类 AI 编程助手,并且恰好也在找工作、想优化简历或者准备面试,那么你很可能已经发现了一个尴尬的现实:这些强大的 AI 工具在生成通用建议时很在行,但一旦涉及到你个人职…...
Docker 27认证新规强制生效倒计时90天,你的PACS/DICOM容器已过期?——2024医疗云平台合规自查清单
更多请点击: https://intelliparadigm.com 第一章:Docker 27医疗容器合规认证新规核心解读 Docker 27于2024年Q3正式发布《医疗健康领域容器化应用合规认证实施细则(V1.0)》,首次将容器镜像签名、运行时完整性校验、H…...
HPH高压均质机内部构造图解
HPH即高压均质机,是制药、食品和化工领域制备微纳米乳液的關鍵设备。它的核心构造并不复杂,但每个部件都直接影响物料的破碎效果。下面我从实际拆解经验出发,带大家看清HPH的几大主要结构。 高压柱塞泵怎么工作 高压柱塞泵作为HPH的动力心脏&…...
Translumo终极指南:如何用免费开源工具实现实时屏幕翻译?[特殊字符][特殊字符]
Translumo终极指南:如何用免费开源工具实现实时屏幕翻译?🎮📖 【免费下载链接】Translumo Advanced real-time screen translator for games, hardcoded subtitles in videos, static text and etc. 项目地址: https://gitcode.…...
从人工标注到自动生成:深入拆解Auto-CoT,如何让大模型自己给自己写‘参考答案’
从人工标注到自动生成:深入拆解Auto-CoT,如何让大模型自己给自己写‘参考答案’ 想象一下,你正在训练一位新入职的算法工程师解决数学应用题。传统方法需要你亲自演示每道题的解题步骤——这就像Few-shot CoT中的人工标注过程,耗时…...
别再手动发邮件了!用Python的smtplib和email库,5分钟搞定邮件自动发送(附Gmail/QQ邮箱配置)
用Python解放双手:5分钟搭建高可靠邮件自动化系统 每天早晨9点准时发送日报,每周五下午3点自动推送周报,批量给客户发送个性化营销邮件...这些重复性工作正在吞噬职场人的宝贵时间。作为曾经每天手动发送30封邮件的过来人,我深刻…...
HS2-HF_Patch终极指南:5分钟掌握Honey Select 2完整汉化与游戏增强
HS2-HF_Patch终极指南:5分钟掌握Honey Select 2完整汉化与游戏增强 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch HS2-HF_Patch是《Honey Select 2…...
揭秘Parse12306:如何用C自动化抓取全国高铁时刻表数据
揭秘Parse12306:如何用C#自动化抓取全国高铁时刻表数据 【免费下载链接】Parse12306 分析12306 获取全国列车数据 项目地址: https://gitcode.com/gh_mirrors/pa/Parse12306 你是否曾为获取权威的铁路数据而烦恼?无论是开发旅行规划应用、进行交通…...
