【C#基础】函数传参大总结
目录
- 前言
- 参数是值类型的情况
- 1. 按值传递(Pass by Value)
- 2. 按引用传递(Pass by Reference)
- 使用 `ref`
- 使用 `in`
- 3. 输出参数传递(Output Parameters)
- 参数修饰符对比
- 小结
- 参数是引用类型的情况
- 1. 按值传递类对象
- 虽然类是引用类型,但默认情况下将类对象传递给函数时,传递的仍是`引用的副本`。
- 2. 按引用传递类对象(`ref`)
- 3. 使用 `out` 参数
- 4. 使用 `in` 参数
- 小结
- 虽然类是引用类型,但默认情况下将类对象传递给函数时,传递的仍是`引用的副本`。
- 最后一问
- 如果传递的是结构体呢?
前言
在C#中,函数传参有三种主要的方式:按值传递、按引用传递和输出参数传递。每种方式的使用场景和效果都不同,下面我将详细讲解这三种方式。
参数是值类型的情况
1. 按值传递(Pass by Value)
这是最常见的参数传递方式。默认情况下,C# 函数的参数是按值传递的。这意味着调用函数时,实参的值会被复制到形参,因此对形参的修改不会影响实参。
void ModifyValue(int x)
{x = 10;
}int number = 5;
ModifyValue(number);
Console.WriteLine(number); // 输出: 5
在这个例子中,number
的值并不会因为函数内部的修改而改变,因为 x
只是 number
的副本。
2. 按引用传递(Pass by Reference)
通过使用 ref
或 in
关键字,可以按引用传递参数。按引用传递时,传递的不是值的副本,而是变量本身的引用。函数可以直接修改原始变量的值。
使用 ref
ref
关键字允许函数修改传递进来的参数的值,并且要求传入的参数必须先初始化。
void ModifyRef(ref int x)
{x = 10;
}int number = 5;
ModifyRef(ref number);
Console.WriteLine(number); // 输出: 10
在这个例子中,number
的值被函数修改了,因为 ref
让参数传递的是引用。
使用 in
in
关键字表示按引用传递,但参数只能在函数内部读取,不能修改。
void ReadValue(in int x)
{Console.WriteLine(x);// x = 10; // 编译错误,不能修改 in 参数
}int number = 5;
ReadValue(in number);
in
参数保证了函数不能修改传递进来的值,只能读取。这对于需要高效传递大型数据结构而不希望其被修改时特别有用。
3. 输出参数传递(Output Parameters)
out
关键字允许函数返回多个值或将数据传递回调用者。与 ref
类似,out
也是按引用传递的,但它不要求变量在传入时已经初始化。函数必须在返回前给 out
参数赋值。
void GetValues(out int x, out int y)
{x = 10;y = 20;
}int a, b;
GetValues(out a, out b);
Console.WriteLine(a); // 输出: 10
Console.WriteLine(b); // 输出: 20
在这个例子中,a
和 b
的值在函数内部被初始化并返回给调用者。
参数修饰符对比
- 按值传递(默认):函数对形参的修改不会影响实参。
ref
:传递引用,形参和实参指向同一个变量,函数可以修改原始变量。in
:按引用传递,但函数只能读取,不可修改。out
:函数必须对参数赋值,用于返回多个值。
小结
C# 提供了灵活的参数传递方式,开发者可以根据需求选择是按值传递、按引用传递还是使用 out
进行输出。这些方式为开发高效、安全的代码提供了很大的帮助。
参数是引用类型的情况
和C++不同,C#的任何class对象都是引用。
在C#中,如果传递的是类对象,情况会有所不同,因为类是引用类型。当你把类对象作为参数传递给函数时,不论是按值传递还是按引用传递,都会对类对象的行为产生影响。让我们仔细看一下如何处理类对象的传递。
1. 按值传递类对象
虽然类是引用类型,但默认情况下将类对象传递给函数时,传递的仍是引用的副本
。
这意味着函数内部对对象属性的修改将会影响到原始对象,因为引用指向的是同一个对象。但如果函数试图重新分配整个对象的引用,外部对象则不会受到影响。
class Person
{public string Name { get; set; }
}void ModifyPerson(Person p)
{p.Name = "Alice"; // 修改属性
}Person person = new Person { Name = "Bob" };
ModifyPerson(person);
Console.WriteLine(person.Name); // 输出: Alice
在上面的例子中,虽然是按值传递,但类对象是引用类型,因此 person
和 p
都引用同一个对象,修改了 p.Name
也会修改 person.Name
。
然而,如果在函数内部重新赋值引用,外部的对象将不会改变:
void ReassignPerson(Person p)
{p = new Person { Name = "Charlie" }; // 重新分配引用
}Person person = new Person { Name = "Bob" };
ReassignPerson(person);
Console.WriteLine(person.Name); // 输出: Bob
在这个例子中,函数内部重新分配了 p
的引用,但这不会影响到外部的 person
对象,因为传递的引用本身是按值传递的副本。
2. 按引用传递类对象(ref
)
使用 ref
关键字时,可以将对象的引用本身传递给函数。这意味着函数可以重新分配对象,并让外部变量反映这种变化。
void ReassignPersonRef(ref Person p)
{p = new Person { Name = "Charlie" }; // 重新分配引用
}Person person = new Person { Name = "Bob" };
ReassignPersonRef(ref person);
Console.WriteLine(person.Name); // 输出: Charlie
在这个例子中,函数通过 ref
传递引用,因此 person
现在指向新的 Person
对象。
3. 使用 out
参数
out
参数的行为与 ref
类似,但要求在函数内部必须对传入的参数赋值。适用于需要从函数返回新的对象或初始化传递进来的对象。
void InitializePerson(out Person p)
{p = new Person { Name = "David" }; // 必须初始化
}Person person;
InitializePerson(out person);
Console.WriteLine(person.Name); // 输出: David
这里,person
是通过 out
参数传递,函数内部必须为其分配一个新对象。
4. 使用 in
参数
in
参数用于按引用传递对象,但它确保对象的引用在函数内部不能被修改。函数可以读取对象的属性和方法,但不能更改引用本身。对于大型对象,它可以避免复制操作,提高效率。
void ReadPerson(in Person p)
{Console.WriteLine(p.Name); // 读取属性是允许的// p = new Person(); // 编译错误,不能修改引用
}Person person = new Person { Name = "Eva" };
ReadPerson(in person);
小结
虽然类是引用类型,但默认情况下将类对象传递给函数时,传递的仍是引用的副本
。
如果能理解这句话,不管是哪种情况,那么思想上就是统一的。
最后一问
如果传递的是结构体呢?
在C#中,**结构体(struct)与类(class)**有一个重要的区别:结构体是值类型,而类是引用类型。因此,如果是结构体,请参考 参数是值类型的情况 !
相关文章:

【C#基础】函数传参大总结
目录 前言参数是值类型的情况1. 按值传递(Pass by Value)2. 按引用传递(Pass by Reference)使用 ref使用 in 3. 输出参数传递(Output Parameters)参数修饰符对比小结 参数是引用类型的情况1. 按值传递类对象…...

初学51单片机之IO口上下拉电阻相关
本案本来是描述一下I2C总线的,在此之前推荐一下B站一个UP关于时序图的讲解 I2C入门第一节-I2C的基本工作原理_哔哩哔哩_bilibili 不过在描述I2C前先简单的探讨下51单片机IO口下拉电阻的基本情况,事实上这个问题困扰笔者很长时间了,这次也是一…...

Resnet50网络——口腔癌病变识别
一 数据准备 1.导入数据 import matplotlib.pyplot as plt import tensorflow as tf import warnings as w w.filterwarnings(ignore) # 支持中文 plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签 plt.rcParams[axes.unicode_minus] False # 用来正常显示负…...

Python 中自动打开网页并点击[自动化脚本],Selenium
要在 Python 中自动打开网页并点击第一个 <a> 标签,你需要使用 Selenium,它可以控制浏览器并执行像点击这样的操作。requests 和 BeautifulSoup 只能获取并解析网页内容,但不能进行网页交互操作。 步骤: 安装 Selenium安装…...

Spring Boot-自动配置问题
**### Spring Boot自动配置问题探讨 Spring Boot 是当前 Java 后端开发中非常流行的框架,其核心特性之一便是“自动配置”(Auto-Configuration)。自动配置大大简化了应用开发过程,开发者不需要编写大量的 XML 配置或是繁琐的 Jav…...

CS61B学习 part1
本人选择了2018spring的课程,因为他免费提供了评分机器,后来得知2021也开放了,决定把其中的Lab尝试一番,听说gitlab就近好评,相当有实力,并借此学习Java的基本知识,请根据pku的cswiki做好评分机…...

我Github的问题解决了!
看的这篇,解决使用git时遇到Failed to connect to github.com port 443 after 21090 ms: Couldn‘t connect to server_git couldnt connect to server-CSDN博客 之前想推送的能推送了,拉取的也能取了。 一、如果是在挂着梯子的情况下拉取或者推送代码…...

Pytorch构建神经网络多元线性回归模型
1.模型线性方程y W ∗ X b from torch import nn import torch#手动设置的W参数(待模型学习),这里设置为12个,自己随意设置weight_settorch.tensor([[1.5,2.38,4.22,6.5,7.2,3.21,4.44,6.55,2.48,-1.75,-3.26,4.78]])#手动设置…...

如何基于Flink CDC与OceanBase构建实时数仓,实现简化链路,高效排查
本文作者:阿里云Flink SQL负责人,伍翀,Apache Flink PMC Member & Committer 众多数据领域的专业人士都很熟悉Apache Flink,它作为流式计算引擎,流批一体,其核心在于其强大的分布式流数据处理能力&…...

ActiveMQ、RabbitMQ 和 Kafka 在 Spring Boot 中的实战
在现代的微服务架构和分布式系统中,消息队列 是一种常见的异步通信工具。消息队列允许应用程序之间通过 生产者-消费者模型 进行松耦合、异步交互。在 Spring Boot 中,我们可以通过简单的配置来集成不同的消息队列系统,包括 ActiveMQ、Rabbit…...

火语言RPA流程组件介绍--获取关联元素
🚩【组件功能】:获取指定元素的父元素、子元素、相邻元素等关联信息 配置预览 配置说明 目标元素 支持T或# 默认FLOW输入项 通过自动捕获工具捕获(选择元素工具使用方法)或手动填写网页元素的css,xpath,指定对应网页元素作为操作目标 关联…...

【2024研赛】【华为杯E题】2024 年研究生数学建模比赛思路、代码、论文助攻
思路将在名片下群聊分享 高速公路应急车道紧急启用模型 高速公路拥堵现象的原因众多,除了交通事故外,最典型的就是部分路段出现瓶颈现象,主要原因是车辆汇聚,而拥堵后又容易蔓延。高速公路一些特定的路段容易形成堵点࿰…...

Linux——K8s集群部署过程
1、环境准备 (1)配置好网络ip和主机名 control: node1: node2: 配置ip 主机名的过程省略 配置一个简单的基于hosts文件的名称解析 [rootnode1 ~]# vim /etc/hosts // 文件中新增以下三行 192.168.110.10 control 192.168.110.11 node1 1…...

二.Unity中使用虚拟摇杆来控制角色移动
上一篇中我们完成了不借助第三方插件实现手游的虚拟摇杆,现在借助这个虚拟摇杆来实现控制角色的移动。 虚拟摇杆实际上就给角色输出方向,类似于键盘的WSAD,也是一个二维坐标,也就是(-1,1)的范围,将摇杆的方向进行归一化…...

基于SpringBoot的旅游管理系统
系统展示 用户前台界面 管理员后台界面 系统背景 近年来,随着社会经济的快速发展和人民生活水平的显著提高,旅游已成为人们休闲娱乐、增长见识的重要方式。国家积极倡导“全民旅游”,鼓励民众利用节假日外出旅行,探索各地自然与人…...

Linux套接字
目录标题 套接字套接字的基本概念套接字的功能与分类套接字的使用流程套接字的应用场景总结套接字在不同操作系统中的实现差异有哪些?如何优化套接字编程以提高网络通信的效率和安全性?原始套接字(SOCK_RAW)的具体应用场景和使用示…...

软件测试面试题(5)——二面(游戏测试)
没想到测试题做完等了会儿就安排面试了,还以为自己会直接挂在测试题,这次面试很刺激。测试题总体来说不算太难,主要是实操写Bug那里真没经历过,所以写的很混乱。 我复盘一下这次面试的问题,这次面试是有两个面试官&…...

C#基于SkiaSharp实现印章管理(8)
上一章虽然增加了按路径绘制文本,支持按矩形、圆形、椭圆等路径,但测试时发现通过调整尺寸、偏移量等方式不是很好控制文本的位置。相对而言,使用弧线路径,通过弧线起始角度及弧线角度控制文本位置更简单。同时基于路径绘制文本时…...

信通院发布首个《大模型媒体生产与处理》标准,阿里云智能媒体服务作为业界首家“卓越级”通过
中国信通院近期正式发布《大模型驱动的媒体生产与处理》标准,阿里云智能媒体服务,以“首批首家”通过卓越级评估,并在9大模块50余项测评中表现为“满分”。 当下,AI大模型的快速发展带动了爆发式的海量AI运用,这其中&a…...

AI学习指南深度学习篇-Adam的Python实践
AI学习指南深度学习篇-Adam的Python实践 在深度学习领域,优化算法是影响模型性能的关键因素之一。Adam(Adaptive Moment Estimation)是一种广泛使用的优化算法,因其在多种问题上均表现优异而被广泛使用。本文将深入探讨Adam优化器…...

08_React redux
React redux 一、理解1、学习文档2、redux 是什么吗3、什么情况下需要使用 redux4、redux 工作流程5、react-redux 模型图 二、redux 的三个核心概念1、action2、reducer3、store 三、redux 的核心 API1、getState()2、dispatch() 四、使用 redux 编写应用1、求和案例\_redux 精…...

2024华为杯研究生数学建模竞赛(研赛)选题建议+初步分析
难度:DE<C<F,开放度:CDE>F。 华为专项的题目(A、B题)暂不进行选题分析,不太建议大多数同学选择,对自己专业技能有很大自信的可以选择华为专项的题目。后续会直接更新A、B题思路&#…...

001.从0开始实现线性回归(pytorch)
000动手从0实现线性回归 0. 背景介绍 我们构造一个简单的人工训练数据集,它可以使我们能够直观比较学到的参数和真实的模型参数的区别。 设训练数据集样本数为1000,输入个数(特征数)为2。给定随机生成的批量样本特征 X∈R10002 …...

Relations Prediction for Knowledge Graph Completion using Large Language Models
文章目录 题目摘要简介相关工作方法论实验结论局限性未来工作 题目 使用大型语言模型进行知识图谱补全的关系预测 论文地址:https://arxiv.org/pdf/2405.02738 项目地址: https://github.com/yao8839836/kg-llm 摘要 知识图谱已被广泛用于以结构化格式表…...

2024年中国研究生数学建模竞赛D题思路代码分析——大数据驱动的地理综合问题
地理系统是自然、人文多要素综合作用的复杂巨系统[1-2],地理学家常用地理综合的方式对地理系统进行主导特征的表达[3]。如以三大阶梯概括中国的地形特征,以秦岭—淮河一线和其它地理区划的方式揭示中国气温、降水、植被、土壤及生态环境在水平和垂直方向…...

全国31省对外开放程度、经济发展水平、政府干预程度指标数据(2000-2022年)
旨在分析2000-2022年间中国31个省份的对外开放程度、经济发展水平和政府干预程度,探讨其背后的动因与影响。 2000年-2022年 全国31省对外开放程度、经济发展水平、政府干预程度指标数据https://download.csdn.net/download/2401_84585615/89478612 数据概览 对外…...

计算机网络传输层---课后综合题
线路:TCP报文下放到物理层传输。 TCP报文段中,“序号”长度为32bit,为了让序列号不会循环,则最多能传输2^32B的数据,则最多能传输:2^32/1500B个报文 结果: 吞吐率一个周期内传输的数据/周期时间…...

【homebrew安装】踩坑爬坑教程
homebrew官网,有安装教程提示,但是在实际安装时,由于待下载的包的尺寸过大,本地git缓存尺寸、超时时间的限制,会报如下错误: error: RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly…...

反游戏学(Reludology):概念、历史、现状与展望?(豆包AI版)
李升伟 以下是关于“反游戏学(Reludology):概念、历史、现状与展望”的综述: 一、概念 反游戏学(Reludology)是一个相对较新且不太常见的概念,目前尚未有统一明确的定义。一般来说…...

【C/C++语言系列】实现单例模式
1.单例模式概念 定义:单例模式是一种常见的设计模式,它可以保证系统中一个类只有一个实例,而且该实例易于外界访问(一个类一个对象,共享这个对象)。 条件: 只有1个对象易于外界访问共享这个对…...