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 方法的结构

  • 返回的数据类型。
  • 方法名称。
  • 参数列表。
image-20231015165612625
图6.1 方法的结构

6.2 方法体内部的代码执行

​ 方法体是一个块,可以包含以下内容:

  • 局部变量;
  • 控制流结构;
  • 方法调用;
  • 内嵌的块;
  • 其他方法(局部函数)。

6.3 局部变量

  • 局部变量的生存周期仅限于创建它的块内。
    • 声明时开始存在。
    • 块尾结束存在。
  • 可以在方法体内部任意位置声明,声明后才能使用。
image-20231015165958072
图6.2 对比实例字段和局部变量

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 值参数

​ 使用值参数时,会发生如下操作:

  1. 在栈中为形参分配空间。
  2. 将实参的值复制给形参。

​ 方法使用值参数不能改变原始的值类型数据,但是可以改变引用类型的数据:

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); // 实参}
}
image-20231015185433612
图6.3 值参数

6.12 引用参数

  • 在方法的声明和调用中都使用 ref 修饰符。
  • 实参必须是已经被赋值的变量,引用类型变量可以是 null。
image-20231015185911962
图6.4 ref 使用说明

​ 引用参数具有如下特征:

  • 不会在栈上为形参分配内存。
  • 形参的参数名将作为实参变量的别名,指向相同的内存位置。
image-20231015190030549
图6.5 对于引用参数,形参就像实参的别名

6.13 引用类型作为值参数和引用参数

​ 对于引用类型对象:

  • 作为值参数传递:如果在方法内创建一个新对象并赋值给形参,对实参没有影响。
  • 作为引用参数传递:如果在方法内创建一个新对象并赋值给形参,则实参也会随之改变。
image-20231015190519645
图6.6 对用作值参数的引用类型对象赋值
image-20231015190632315
图6.7 为用作引用参数的引用类型对象赋值

​ 将引用类型对象作为引用参数传递,目的是改变引用对象;

​ 如果仅需改变引用类型对象的内容,只需值参数传递即可。

6.14 输出参数

  • 在方法的声明和调用中都使用 out 修饰符。
  • 实参必须是变量,使用前可以不赋值。
  • 形参的参数名也作为实参变量的别名,指向相同的内存位置。
image-20231015190939239
图6.8 out 使用说明

​ 与 ref 不同,out 有如下要求:

  1. 给输出参数赋值后才能读取。
  2. 方法返回之前,必须给输出参数赋值。

​ C# 7.0 后,可以对输出参数进行简化声明,不需要预先声明一个变量来用作 out 参数了。如图 6.9 所示,声明后的 a1 和 a2 可以在方法调用结束后继续使用。

image-20231015191333370
图6.9 out 新的声明方式

6.15 参数数组

  • 在形参前使用 params 修饰符,并在数据类型后放置一组方括号。
  • 参数列表中只能有一个参数数组,且必须为参数列表的最后一个。
  • 参数数组中的所有参数类型必须相同。
image-20231015191753290
图6.10 params 使用说明

6.15.1 方法调用

​ 可以使用两种方式为参数数组提供实参:

  1. 使用逗号分隔的元素列表。
ListInts(10, 20, 30); // 3 个 int
  1. 一个同类型的一维数组。
int[] intArray = {1, 2, 3};
ListInts(intArray);

​ 注意:在调用时不使用 params 修饰符。

​ 使用独立实参调用时,编译器将执行以下步骤:

  1. 接受实参列表,在堆中创建并初始化一个数组;
  2. 把数组的引用保存到栈中的形参里;
  3. 如果没有实参(个数为 0),则编译器会创建一个具有 0 个元素的数组来使用。
void ListInts(params int[] inVals) { ... } // 方法声明...
ListInts();              // 0 个实参
ListInts(1, 2, 3);       // 3 个实参
ListInts(4, 5, 6, 7, 8); // 5 个实参

​ 当数组 inVals 在堆中被创建时,实参的值被赋值到数组中,因此可看做值参数:

  • 数组参数为值类型:值被复制,实参不受影响;
  • 数组参数为引用类型:引用被复制,实参引用的对象在内部会受到影响。
image-20231015192755242
图6.11 参数数组示例

6.15.2 将数组作为实参

​ 编译器将使用传入的数组而不是重新创建一个。

6.16 参数类型总结

image-20231015192951213
图6.12 参数类型语法使用总结

6.17 ref 局部变量和 ref 返回

​ 创建别名的语法需要使用 ref 两次。

image-20231015193051479
图6.13 创建 ref 局部变量

​ ref 返回使得方法可以返回引用而不是值,同样也需要使用两次 ref:

image-20231015193219646
图6.14 ref 返回示例

​ 有关 ref 的使用有如下注意事项:

  1. ref return 不能返回如下内容:
    • 空值。
    • 常量。
    • 枚举成员。
    • 类或结构体的属性。
    • 指向只读位置的指针。
  2. ref return 不能返回方法内部的局部变量;
  3. ref 局部变量只能被赋值一次,后面出现的等号表示赋值;
  4. 如果调用 ref 返回方法时未使用 ref 关键字,则返回的是值而不是引用;
  5. 将 ref 局部变量作为常规的实际参数传递给其他方法时,传递的仍是 ref 指向的副本而不是引用。

6.18 方法重载

​ 使用相同名称的方法必须和其他同名方法有不同的签名,签名由如下信息组成:

  • 方法名称。
  • 参数数目。
  • 参数的数据类型和顺序。
  • 参数修饰符。

​ 返回类型和形参名称都不是签名的一部分。

image-20231015212331455
图6.15 签名组成成分

6.19 命名参数

​ C# 可以使用命名参数,显示指定参数的名称,就能够以任意顺序在方法中列出实参。

image-20231015212314102
图6.16 命名参数示例

​ 可以同时使用位置参数和命名参数,但所有位置参数必须先列出。

image-20231015212232064
图6.17 位置参数和命名参数同时使用

6.20 可选参数

​ 可选参数能够设置参数的默认值,图 6.18 列出了哪些时候能使用可选参数。

image-20231015212147383
图6.18 可选参数只能是值参数类型

​ 所有必填参数需放在可选参数声明之前,params 参数放在可选参数之后,如图 6.19 所示。

image-20231015212530555
图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 递归(*)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/106231.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql面试题50:500台数据库,如何在最快时间之内重启

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:500台db,如何在最快时间之内重启呢? 如果需要在最快时间内重启500台数据库,可以考虑采用并行化和自动化的方法来提高效率。比如: 编写自动化脚…

vh、vw、vmin、vmax

1、分别是什么? vh:指屏幕可见视窗的高, vw:指屏幕可见视窗的宽, vmin:vh和vw之间选较小的值, vmax:vh和vw之间选较大的值。 2、和百分比的区别 百分比时基于父元素的宽高,而vh\vw\vmin\vmax基于屏幕可见视图的宽…

protobuf 插件(option)使用

protobuf的option使用 一、需求 来源于工作中的一个需求:在传递message时需要对message中不同的字段进行不同的处理,而处理方式通过注释标注在了每个字段的定义后。 类似于有下面这样一个消息: 其中字段1是始终需要的,字段2和3…

Mall脚手架总结(五) —— SpringBoot整合MinIO实现文件管理

前言 在项目中我们经常有资源的上传和下载的功能需求,比如用户头像、产品图片、配置文件等等,大数据量的文件存储无疑需要更高性能的数据存储服务,对于无需对结构实现复杂查询的文件对象来说,对象存储服务无疑是一个较好的选择&am…

uniapp编译到小程序Component is not found in path “components/energy/illumination“

Component is not found in path "components/energy/illumination" 直接清除缓存重新编译

Ubuntu下怎么配置vsftpd

2023年10月12日,周四中午 目录 首先要添加一个系统用户然后设置这个系统用户的密码给新创建的系统用户创建主目录启动vsftpd服务查看vsftpd服务的状态打开外界访问vsftpd服务所需的端口获取服务器的IP地址大功告成 首先要添加一个系统用户 useradd 用户名然后设置…

APP备案避坑指南,值得收藏

目录 什么时间节点前需完成备案? APP/小程序一定要做备案吗? 涉及前置审批的APP有哪些? APP 支持安卓、IOS 多个运行平台,应该备案多少次? 企业是自有服务器,该如何进行APP备案? APP备案可…

【Spring框架】Spring监听器的简介和基本使用

目录 一、观察者模式 1.1 模型介绍 1.2 观察者模式Demo 1.2.1 观察者实体 1.2.2 主题实体 1.2.3 测试代码 二、Spring监听器的介绍 2.1 事件(ApplicationEvent) 2.1.1 Spring内置事件 2.1.2 Spring内置事件 2.2 事件监听器(Applic…

三大方法快速发现商业规律

文章目录 三大方法快速发现商业规律一、市场调研二、数据分析三、案例分析 📕我是廖志伟,一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作者、产品软文创造者、技术文章评审老师、问卷调查…

PHP LFI 利用临时文件Getshell

PHP LFI 利用临时文件 Getshell 姿势-安全客 - 安全资讯平台 LFI 绕过 Session 包含限制 Getshell-安全客 - 安全资讯平台 目录 PHP LFI 利用临时文件Getshell 临时文件 linux 和 windows的 临时文件存储规则 linux和windows对临时文件的命名规则 PHPINFO()特性 原理 条…

Python点击exe后报错:Failed to execute script xxxx问题的解决办法

最近工作在弄人脸识别的问题,从gitee来pull了一个但是发现报了一个Failed to execute script XXX的问题 造成这个问题的原因是执行文件exe存放的目录不对,可能在打包前exe文件并不是存在在这个位置。 解决方案将exe文件尝试存在在不同目录下&#xff…

详解Pinia和Vuex

一、vuex介绍 1.什么是vuex?为什么要使用vuex? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 在vue最重要的就是数据驱动和组件化&#x…

Qt之submodule编译

工作中会遇到这样一种情况:qt应用程序在运行时提示找不到某个qt的动态库。我遇到的是缺少libQt5Websocket.so,因为应用程序是在x86平台银河麒麟v10上开发,能够正常编译运行,然后移植到rk3588(aarch64架构)上…

NeuroImage | 右侧颞上回在语义规则学习中的作用:来自强化学习模型的证据

在现实生活中,许多规则的获取通常需要使用语言作为桥梁,特别是语义在信息传递中起着至关重要的作用。另外,个体使用的语言往往具有明显的奖励和惩罚元素,如赞扬和批评。一种常见的规则是寻求更多的赞扬,同时避免批评。…

【翻译】Efficient Data Loader for Fast Sampling-Based GNN Training on Large Graphs

转载请注明出处:小锋学长生活大爆炸[xfxuezhang.cn] 此内容为机器翻译的结果,若有异议的地方,建议查看原文。 机器翻译的一些注意点,比如: 纪元、时代 > epoch工人 > worker火车、培训、训练师 > train Effic…

c# 弹出背景透明图

1. 在窗体中添加 picturebox 控件 2. 在 picturebox 中添加 “png ” 背景透明图,或者GIF图,属性设置如下 3. 在窗体初始化中,添加如下代码 this.BackColor Color.LimeGreen; this.TransparencyKey Color.LimeGreen; 此功能可以用来展示…

【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?

文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 面试官:vue项目本地开发完成后部…

一卷到底,大明哥带你横扫 Netty

上一个死磕 Java 专栏【死磕 NIO】(当然写的不是很好,争取今年将它重写一遍)是**【死磕 Netty】**的铺垫,对于我们 Java 程序员而言,我们在实际开发过程一般都不会直接使用 Java NIO 作为我们的网络编程框架,因为写出一套高质量的…

基于和声优化的BP神经网络(分类应用) - 附代码

基于和声优化的BP神经网络(分类应用) - 附代码 文章目录 基于和声优化的BP神经网络(分类应用) - 附代码1.鸢尾花iris数据介绍2.数据集整理3.和声优化BP神经网络3.1 BP神经网络参数设置3.2 和声算法应用 4.测试结果:5.M…

内网渗透——隧道代理

文章目录 代理代理使用场景VPS建立隧道frpMSF木马生成监听开启frp服务端和客户端执行exe木马文件 代理 实验环境: 攻击机kali:192.168.188.133(NAT模式) 模拟的公网服务器(本机):10.9.75.239 …