C# 图解教程 第5版 —— 第6章 方法
文章目录
- 6.1 方法的结构
- 6.2 方法体内部的代码执行
- 6.3 局部变量
- 6.3.1 类型推断和 var 关键字
- 6.3.2 嵌套块中的局部变量
- 6.4 局部常量
- 6.5 控制流
- 6.6 方法调用(*)
- 6.7 返回值(*)
- 6.8 返回语句和 void 方法
- 6.9 局部函数
- 6.10 参数(*)
- 6.11 值参数
- 6.12 引用参数
- 6.13 引用类型作为值参数和引用参数
- 6.14 输出参数
- 6.15 参数数组
- 6.15.1 方法调用
- 6.15.2 将数组作为实参
- 6.16 参数类型总结
- 6.17 ref 局部变量和 ref 返回
- 6.18 方法重载
- 6.19 命名参数
- 6.20 可选参数
- 6.21 栈帧
- 6.22 递归(*)
6.1 方法的结构
- 返回的数据类型。
- 方法名称。
- 参数列表。
6.2 方法体内部的代码执行
方法体是一个块,可以包含以下内容:
- 局部变量;
- 控制流结构;
- 方法调用;
- 内嵌的块;
- 其他方法(局部函数)。
6.3 局部变量
- 局部变量的生存周期仅限于创建它的块内。
- 声明时开始存在。
- 块尾结束存在。
- 可以在方法体内部任意位置声明,声明后才能使用。
6.3.1 类型推断和 var 关键字
使用 var 关键字可以进行类型推断,而不需要明确指定变量类型。var 关键字并不改变 C# 的强类型性质。
- 只能用于局部变量,不能用于字段。
- 只能在变量声明中包含初始化时使用。
- 一旦编译器推断出变量的类型,它就是固定且不能更改的。
6.3.2 嵌套块中的局部变量
在 C# 中不论嵌套级别如何,都不能在第一个名称的有效范围内声明另一个同名的局部变量。
6.4 局部常量
- 声明时必须初始化。
- 初始化值必须在编译时就可以确定,通常为预定义简单类型或 null 引用。
- 声明后不能改变。
和局部变量一样,局部常量声明在方法体或代码块里,并在声明它的块结束的地方失效。
注意:const 不是修饰符,而是核心声明的一部分。
6.5 控制流
- 选择语句
- if
- if … else
- switch
- 迭代语句
- for
- while
- do
- foreach
- 跳转语句
- break
- continue
- goto
- return
6.6 方法调用(*)
6.7 返回值(*)
6.8 返回语句和 void 方法
6.9 局部函数
C# 7.0 开始,可以在一个方法中声明另一个单独的方法,称为局部函数。
6.10 参数(*)
6.11 值参数
使用值参数时,会发生如下操作:
- 在栈中为形参分配空间。
- 将实参的值复制给形参。
方法使用值参数不能改变原始的值类型数据,但是可以改变引用类型的数据:
class MyClass { public int Val = 20; }class Program {static void MyMethod(MyClass f1, int f2) { // 形参f1.Val = f1.Val + 5;f2 = f2 + 5;}static void Main() {MyClass a1 = new MyClass();int a2 = 10;MyMethod(a1, a2); // 实参}
}
6.12 引用参数
- 在方法的声明和调用中都使用 ref 修饰符。
- 实参必须是已经被赋值的变量,引用类型变量可以是 null。
引用参数具有如下特征:
- 不会在栈上为形参分配内存。
- 形参的参数名将作为实参变量的别名,指向相同的内存位置。
6.13 引用类型作为值参数和引用参数
对于引用类型对象:
- 作为值参数传递:如果在方法内创建一个新对象并赋值给形参,对实参没有影响。
- 作为引用参数传递:如果在方法内创建一个新对象并赋值给形参,则实参也会随之改变。
将引用类型对象作为引用参数传递,目的是改变引用对象;
如果仅需改变引用类型对象的内容,只需值参数传递即可。
6.14 输出参数
- 在方法的声明和调用中都使用 out 修饰符。
- 实参必须是变量,使用前可以不赋值。
- 形参的参数名也作为实参变量的别名,指向相同的内存位置。
与 ref 不同,out 有如下要求:
- 给输出参数赋值后才能读取。
- 方法返回之前,必须给输出参数赋值。
C# 7.0 后,可以对输出参数进行简化声明,不需要预先声明一个变量来用作 out 参数了。如图 6.9 所示,声明后的 a1 和 a2 可以在方法调用结束后继续使用。
6.15 参数数组
- 在形参前使用 params 修饰符,并在数据类型后放置一组方括号。
- 参数列表中只能有一个参数数组,且必须为参数列表的最后一个。
- 参数数组中的所有参数类型必须相同。
6.15.1 方法调用
可以使用两种方式为参数数组提供实参:
- 使用逗号分隔的元素列表。
ListInts(10, 20, 30); // 3 个 int
- 一个同类型的一维数组。
int[] intArray = {1, 2, 3};
ListInts(intArray);
注意:在调用时不使用 params 修饰符。
使用独立实参调用时,编译器将执行以下步骤:
- 接受实参列表,在堆中创建并初始化一个数组;
- 把数组的引用保存到栈中的形参里;
- 如果没有实参(个数为 0),则编译器会创建一个具有 0 个元素的数组来使用。
void ListInts(params int[] inVals) { ... } // 方法声明...
ListInts(); // 0 个实参
ListInts(1, 2, 3); // 3 个实参
ListInts(4, 5, 6, 7, 8); // 5 个实参
当数组 inVals 在堆中被创建时,实参的值被赋值到数组中,因此可看做值参数:
- 数组参数为值类型:值被复制,实参不受影响;
- 数组参数为引用类型:引用被复制,实参引用的对象在内部会受到影响。
6.15.2 将数组作为实参
编译器将使用传入的数组而不是重新创建一个。
6.16 参数类型总结
6.17 ref 局部变量和 ref 返回
创建别名的语法需要使用 ref 两次。
ref 返回使得方法可以返回引用而不是值,同样也需要使用两次 ref:
有关 ref 的使用有如下注意事项:
- ref return 不能返回如下内容:
- 空值。
- 常量。
- 枚举成员。
- 类或结构体的属性。
- 指向只读位置的指针。
- ref return 不能返回方法内部的局部变量;
- ref 局部变量只能被赋值一次,后面出现的等号表示赋值;
- 如果调用 ref 返回方法时未使用 ref 关键字,则返回的是值而不是引用;
- 将 ref 局部变量作为常规的实际参数传递给其他方法时,传递的仍是 ref 指向的副本而不是引用。
6.18 方法重载
使用相同名称的方法必须和其他同名方法有不同的签名,签名由如下信息组成:
- 方法名称。
- 参数数目。
- 参数的数据类型和顺序。
- 参数修饰符。
返回类型和形参名称都不是签名的一部分。
6.19 命名参数
C# 可以使用命名参数,显示指定参数的名称,就能够以任意顺序在方法中列出实参。
可以同时使用位置参数和命名参数,但所有位置参数必须先列出。
6.20 可选参数
可选参数能够设置参数的默认值,图 6.18 列出了哪些时候能使用可选参数。
所有必填参数需放在可选参数声明之前,params 参数放在可选参数之后,如图 6.19 所示。
- 必须从可选参数列表的最后向前开始省略,而不是任意省略参数。
- 如果需要任意省略参数,需要配合命名参数来实现以消除赋值的歧义。
class MyClass {double GetCylinderVolume(double radius = 3.0, double height = 4.0) {return 3.1416 * radius * radius * height;}static void Main() {MyClass mc = new MyCalss();double volume;volume = mc.GetCylinderVolume(3.0, 4.0); // 位置参数volume = mc.GetCylinderVolume(radius: 2.0); // 使用 height 默认值volume = mc.GetCylinderVolume(height: 2.0); // 使用 radius 默认值volume = mc.GetCylinderVolume(); // 使用两个默认值}
}
6.21 栈帧
调用方法时,内存从栈的顶部开始分配,保存和方法关联的一些数据项。这块内存称为方法的栈帧。
- 栈帧包含如下内容:
- 返回地址,即方法返回时继续执行的位置。
- 分配内存的参数,即值参数(参数数组,如果有的话)。
- 和方法调用相关的其他管理数据项。
- 在方法调用时,整个栈帧都会压入栈。
- 方法退出时,整个栈帧会从栈上弹出,也称栈展开。
6.22 递归(*)
相关文章:
C# 图解教程 第5版 —— 第6章 方法
文章目录 6.1 方法的结构6.2 方法体内部的代码执行6.3 局部变量6.3.1 类型推断和 var 关键字6.3.2 嵌套块中的局部变量 6.4 局部常量6.5 控制流6.6 方法调用(*)6.7 返回值(*)6.8 返回语句和 void 方法6.9 局部函数6.10 参数&#…...
283 移动零
解题思路: \qquad 适用双指针,l:最左边‘0’元素坐标;r:l右边第一个非零元素坐标。 \qquad 最初的思路:将l和r初始化为0,遍历数组nums若任意一个指针到达数组末尾时停止。若当前nums[l] 0则移…...
maven 编译.../maven-metadata.xml 报错
文章目录 问题解决 问题 突然编译报错: 解决 打开maven的里离线工作模式,感觉就是下载包到本地. 一个是在maven设置里面 或者直接在maven编译的窗口:...
【Rust笔记】Rust与Java交互-JNI模块编写-实践总结
近期工作中有Rust和Java互相调用需求,这篇文章主要介绍如何用Rust通过JNI和Java进行交互,还有记录一下开发过程中遇到的一些坑。 JNI简单来说是一套Java与其他语言互相调用的标准,主要是C语言,官方也提供了基于C的C接口。 既然是C…...
uniapp:幸运大转盘demo
<template><view class"index"><image src"../../static/img/158.png" mode"" class"banner"></image><view class"title">绿色积分加倍卡拿到手软</view><almost-lottery :lottery…...
android 13.0 通过系统自定义服务控制屏幕亮屏和灭屏操作
1.前言 在13.0的产品开发中, 需要提供亮屏和灭屏的接口在8.0以后系统对于屏幕亮灭屏做了限制,直接调用亮屏和灭屏的方法就调不到了,所有就需要通过增加自定义服务的功能,来实现 通过系统服务的方法来调用系统关于控制屏幕亮屏灭屏的相关操作 2.通过系统自定义服务控制屏幕…...
【SQL】新建库表时,报错attempt to write a readonly database
目录 1.问题背景 2.问题原因 3.解决方式 4.结果 windows64位 Navicat sql vscode c 1.问题背景 需求是这样: 希望在调用初始化数据库方法时,查看是否有名为【POCT_PROCESS_CONFIG】的数据库表,如果没有就新建 我的数据库格式是这样 …...
C++ --STL
STL STL(Standard Template Library,标准模板库)STL从广义上分为: 容器(container)算法 (algorithm)迭代器 (iterator) 容器 和 算法之间通过迭代器进行无缝连接。STL几乎所有的代码都采用模板类或者模板函数 1、ST…...
一卷到底,大明哥带你横扫 Netty
上一个死磕 Java 专栏【死磕 NIO】(当然写的不是很好,争取今年将它重写一遍)是**【死磕 Netty】**的铺垫,对于我们 Java 程序员而言,我们在实际开发过程一般都不会直接使用 Java NIO 作为我们的网络编程框架,因为写出一套高质量的…...
Python Opencv实践 - 车辆统计(1)读取视频,移除背景,做预处理
示例中的图像的腐蚀、膨胀和闭运算等需要根据具体视频进行实验得到最佳效果。代码仅供参考。 import cv2 as cv import numpy as np#读取视频文件 video cv.VideoCapture("../../SampleVideos/Traffic.mp4") FPS 10 DELAY int(1000 / FPS) kernel cv.getStructu…...
ROS-6.参数的使用
参数的使用 参数服务结构命令行的使用方式运行小海龟命令介绍查看参数获取参数值设置参数保存参数到文件从文件导入参数 通过程序操作创建节点修改cmake编译运行 参数服务结构 ros中存在参数服务管理服务,管理这所有参数,所有节点剋订阅和发布这些节点 …...
机器视觉在自动驾驶汽车中的应用与挑战
机器视觉在自动驾驶汽车中扮演着至关重要的角色,它使车辆能够感知和理解周围环境,以便自主驾驶。以下是机器视觉在自动驾驶汽车中的应用以及相关挑战: 应用: 障碍物检测与避让: 机器视觉系统可以检测和识别路上的障碍…...
欠拟合、过拟合及优化:岭回归
问题:训练数据训练的很好啊,误差也不大,为什么在测试集上面有问题呢? 当算法在某个数据集当中出现这种情况,可能就出现了过拟合现象。 1、 什么是过拟合与欠拟合 欠拟合 过拟合 分析 第一种情况:因为机器学习到的天鹅特征太少了,导致区分标准太粗糙,不能准确识别出天鹅…...
Mybatis学习笔记注解/xml映射/动态SQL%%%Mybatis教程
介绍 Mybatis 是一款优秀的持久层框架,用于简化 JDBC 的开发 MyBatis中文网 Mybatis 入门 快速入门 步骤 创建 SpringBoot 工程、数据库表 user、实体类 User引入 Mybatis 相关依赖,配置 Mybatis(数据库连接信息)编写 SQL 语…...
Git纯操作版 项目添加和提交、SSH keys添加、远程仓库控制、冲突解决、IDEA连接使用
Git 文章目录 Git项目简单克隆通用操作添加和提交回滚分支变基分支优选 远程项目推送认证抓取、拉取和冲突解决 IEDA类软件连接 最近学原理学的快头秃了,特此想出点不讲原理的纯操作版,不过还是放个图吧 项目简单克隆 git在本人日常中最重要的功能还是…...
使用OpenSSL生成自签证书
什么是OpenSSL OpenSSL是一个开源的软件库和工具套件,用于安全地处理网络数据传输中的加密、解密、安全套接层(SSL)以及传输层安全(TLS)协议等功能。它广泛应用于网站和互联网服务中,以确保数据传输的安全…...
Spring源码解析——Spring事务是怎么通过AOP实现的?
正文 此篇文章需要有SpringAOP基础,知道AOP底层原理可以更好的理解Spring的事务处理。最全面的Java面试网站 自定义标签 对于Spring中事务功能的代码分析,我们首先从配置文件开始人手,在配置文件中有这样一个配置:<tx:annot…...
机器人革命:脑洞大开的前沿机器人技术!
原创 | 文 BFT机器人 01 由生物启发的多模式移动形态机器人 在一个不断运动的世界中,一种新开发的名为M4(多模式移动形态机器人)的机器人展示了在包括滚动、飞行和行走在内的八种不同运动模式之间切换的能力。这款机器人由加州理工学院自主…...
微信小程序动态海报
参考文献: 微信小程序生成分享海报(附带二维码生成) - 简书 需求背景: 微信小程序固定图片,无法自动链接,分享页面内容 解决方案: 拆分海报内容,由以下几个组成 1、用户图像 …...
手写单例模式
一、单例模式的定义 定义: 确保一个类只有一个实例,并提供该实例的全局访问点。 这样做的好处是:有些实例,全局只需要一个就够了,使用单例模式就可以避免一个全局使用的类,频繁的创建与销毁,耗…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...
spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...
Java数组Arrays操作全攻略
Arrays类的概述 Java中的Arrays类位于java.util包中,提供了一系列静态方法用于操作数组(如排序、搜索、填充、比较等)。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序(sort) 对数组进行升序…...
