c#笔记-方法

news2024/9/26 3:26:38

方法

方法定义

方法可以将一组复杂的代码进行打包。
声明方法的语法是返回类型 + 方法名 + 括号 + 方法体

void Hello1()
{
	for (int i = 0; i < 10; i++)
	{
		Console.WriteLine("Hello");
	}
}

调用方法

方法的主要特征就是他的括号。
调用方法的语法是方法名+括号

Hello1();

当调用方法时,就会执行方法体内的代码。
在多个地方需要使用同一组复杂代码时,使用方法打包,会减少代码量。
相较于直接复制这些代码,打包成方法更方便后续的修改。
只需要修改方法体内部的代码,所有调用方法的地方执行的代码都会被修改。

作用域

方法体的声明也有一个大括号,所以这也是一个作用域。
在大括号里声明的东西,不能在大括号外访问。
如果Int2定义在一个if块中也是同样的效果。

void Int1()
{
	int i1 = 10;//这个变量只能在Int1内部访问
	void Int2()//这个方法只能在Int1内部访问
	{
		int i2 = i1;//允许访问
	}
}
Int2();//无法访问,超出作用域
i1 = 5;//无法访问,超出作用域

返回值

void表示方法不会返回值。它可以改成一个具体类型,方法在调用完毕后就会返回这个类型的值。
必须在方法内部使用return指明要返回的值。

string String1()
{
	var i = Random.Shared.Next(100);
	return $"{i * i}";
}

在调用方法的时候,这个方法就可以被认为是一个值,可以用来给变量赋值,或是参与到表达式计算中。

string s1 = "随机数是" + String1();

流程控制

return同时有结束方法的作用。在void方法中不能在后面跟随值来返回,但可以单独使用来结束方法。

void Random1()
{
	while (true)
	{
		int i = Random.Shared.Next(100);
		Console.WriteLine("随机数是" + i);
		if (i < 5)
		{
			return;
		}
	}
}

但是对于有返回值的方法,在必须使用return来结束方法(如果方法能结束,即没有死循环)。
如果使用了流程控制语句,需要注意,你认为必定会执行的流程,编译器可能不会这么认为。

int Int3()
{
	int i = 0;
	while (i < 100)
	{
		i++;
		return i;
	}
	return i;//尽管你认为这个方法必然会从上面的循环中返回。
			 //但对编译器来说那个循环可能完全不会执行。
			 //必须要在方法结束的地方另外写一个返回语句。
}

方法调用可以单独作为语句一行放置。
如果它有返回值而你不需要用到他的值,不需要做额外的处理,当作无返回值的方法就行。

引用返回值

引用变量也是有效的返回值类型。

ref int Int4()
{
	int[] arr = new int[1];
	return ref arr[0];
}

返回引用变量的方法可以取引用,也可以直接取值。

ref int i2 = ref Int4();
int i3 = Int4();

参数

声明方法的时候,可以在方法的括号里声明变量。
他们不需要赋值初始值。多个参数用逗号隔开,并且要写明类型,即便他们类型相同。

int Max1(int i1, int i2, int i3)
{
	if (i1 > i2)
	{
		return i1 > i3 ? i1 : i3;
	}
	else
	{
		return i2 > i3 ? i2 : i3;
	}
}

在调用方法的时候,需要在括号里填入对应的值。
使用逗号隔开,顺序和类型都对应上。
这些值将作为初始值赋值给这些参数。

int i4 = Max1(9, 6, 8);
Console.WriteLine(i4);//9

捕获与隔离

方法里可以直接使用外部的变量。这称为捕获变量。
任何对捕获变量的修改都会直接作用到它身上。

int i5 = 40;
Hello2();
Console.WriteLine(i5);//6
void Hello2()
{
	i5 = 6;
}

在这里插入图片描述
而方法的参数可以声明和作用域外部同名的参数。
这样在方法内对它的修改只会改动到参数,不会影响到外部同名的变量。

int i6 = 40;
Hello3(0);
Console.WriteLine(i6);//40
void Hello3(int i5)
{
	i5 = 6;
}

可选参数

参数可以赋值初始值,但必须是常量,或者default。
如果一个参数有初始值,那么他们之后的所有变量都要有初始值。

void Random2(int max = 100, int critical = 20)
{
	if (Random.Shared.Next(max) < critical)
	{
		Console.WriteLine("暴击");
	}
	else
	{
		Console.WriteLine("没有暴击");
	}
}

有初始值的参数在调用的时候可以不必填入初始值,
也可以正常填入值来覆盖预定义的初始值。

Random2();
Random2(40);
Random2(1000, 800);

不定长参数

如果参数的最后一个变量是数组,那么可以使用params修饰。
params修饰的数组不能有默认值。所以不定长参数和可选参数不能同时使用)

int Min1(params int[] arr)
{
	if (arr.Length == 0)
		return 0;
	int min = arr[0];
	for (int i = 1; i < arr.Length; i++)
	{
		if (min < arr[i])
			min = arr[i];
	}
	return min;
}

在调用的时候可以直接传入一个数组,
也可以以散装的形式填入。

Min1();
Min1(1);
Min1(6,9);
Min1(8,4,2);

命名参数

默认情况下,调用方法时需要按照参数在定义时的顺序来填入。
但如果指明这个值是给哪个参数的,那么可以乱序。

Hello4(b: 8, a: 9, d: 10);//输出9,8,6,10

void Hello4(int a, int b, int c = 6, int d = 40)
{
	Console.WriteLine(a);
	Console.WriteLine(b);
	Console.WriteLine(c);
	Console.WriteLine(d);
}

这种方式可以在有多个可选参数时,保持前面可选参数的默认值。

引用参数

参数可以设置为引用变量,在前面加上ref

void Hello5(ref int i)
{
	i *= 2;
}

就像给引用变量赋值时一样,在调用方法时也需要加上ref来把变量取指针。

int i7 = 10;
Hello5(ref i7);
Console.WriteLine(i7);//20

元组

元组类型

方法的返回类型是固定的,不能在某种条件下返回int,在另一种条件下返回bool。
但是可以把这两个数据打包一起返回。这需要一种包含多种数据,却是单独的类型。

除了数组可以打包多个同种类型数据外,元组可以打包固定数量和确定类型的数据。
元组的声明为把多个类型以逗号分隔,然后把他们加上小括号。

(string, int) Hello6((string, int) stu)
{
	return stu;
}

打包和析构

将同样数量,顺序,类型的一堆值,以逗号分隔,打上括号,就能打包成一个元组类型。

(string, int) stu1 = ("小明", 18);//声明元组,并为元组赋值
(string name1, int age1) = stu1;//析构元组,声明两个变量接收他们
Console.WriteLine(name1);
Console.WriteLine(age1);

在元组类型后加上变量名,是一个元组类型的声明。
如果不加变量名,那么就是元组的析构。
元组会把打包的数据依次赋值给这些变量。

析构的时候可以声明变量,也可以对已有的变量覆盖值。
在析构时,可以使用下划线_来舍弃一些值。
直接使用打包和析构,可以在单语句中交换变量的值。

int id2;
(_, int age2, id2) = ("小明", 18, 1006);//析构元组,舍弃一个值,声明一个变量,覆盖一个已有变量
(age2, id2) = (id2, age2);//交换age2和id2的值

元素命名

无命名

元组中的元素可以单独访问和修改。
任何情况下,元组中的元素都可以使用Item1Item2Item3这种形式访问(从1开始计数)

(string, int) stu3 = ("小明", 18);
string name3 = stu3.Item1;
stu3.Item2 = 66;

类型命名

在声明元组类型时,可以为元素直接命名。
命名后依然可以使用Item1Item2Item3进行访问,并且不可指定这些值作为名字。

(string name, int age) stu4 = ("小明", 18);
string name4 = stu4.name;
stu4.Item2 = 66;

值命名

如果使用var来声明元组,可以在声明值的时候为值指定元素名。

var stu5 = (name: "小明", age: 18);
var name5 = stu5.name;
stu5.age = 88;

推断命名

如果你使用var来声明元组,并且没有给值指定名字,但你使用的是变量,不是表达式,常量,方法。
那么会使用变量名来作为元素名。

string s1 = "hello";
var slength = (s1, s1.Length);
var length = slength.Length;
slength.s1 = "world";

可空值类型

在设置值类型的参数时,我们可能需要一些更特殊的值,而不是default。
例如,将一个int的默认值设置为0,我们无法分辨到底是没有填写保持默认值,
还是真的需要以0为参数来做处理。

我们可以使用可空值类型,在值类型后加上?,他将可以接收null值。

int Random3(int max = 100, int? min = null)
{
	if (min == null)
		return Random.Shared.Next(max);
	else
		return Random.Shared.Next(min.Value, max);
}

可空值类型是他原本类型的包装类型。
他有两个属性,HasValueValue
HasValue是判断这个值有没有值,效果和==null一样。
如果有值,使用Value访问他的值。但是如果是null,这个访问会报错。

提升运算符

可空值类型继承了基础类型的运算符,这一特性是配合编译器联合工作的结果,我们无法复刻。
可空值类型在使用基础类型的运算符时,遵循以下规则:

  • 如果没有null参与,按基础类型的方式执行。但返回值为可空值类型。
  • 当使用关系运算符时
    • 当双方为null且使用==运算时,返回true
    • 当仅一方为null且使用!=运算时,返回true
    • 否则返回false
  • 如果对于逻辑运算符,如果是true||y,返回true。如果是false&&y返回false
  • 其他二元运算符返回null

空传播

在你访问一个值的内容时,可以在.[前面加个?,表示空传播。
只要左侧的值是null,那么会阻止之后的所有内容访问,不会异常,并且返回null

string[]? arr1 = null;
string? s2 = arr1?[0];//不会阻止索引越界
int? i8 = s2?.Length;
var i9 = arr1?[0].Length;//只要arr1是null,后面的.Length也不会执行

如果是值类型,那么空传播就会返回可空值类型。
对可空值类型使用时,会直接访问到Value的内容。

int? i10 = 2;
var s3 = i10.Value.ToString();
var s4 = i10?.ToString();

空容忍

对引用类型加?不会发生什么事,因为他们本来就可以接收null值。
只不过如果你不加?,编译器会认为你不希望这个变量接收一个null值,
在赋值的时候他会分析这些值,如果可能是null就会向你发出警告。
在这里插入图片描述
如果你不希望提示这个警告,可以在值的右侧加上!,表示我不在乎他是不是null

int? i11 = 10;
string s5 = i11?.ToString()!;

合并运算

使用x ?? y运算符来简写x == null ? x : y
同样有他的赋值复合运算。

string s6 = null;
int i11 = s6?.Length ?? -1;
s6 ??= "hello";

如果合并运算表达式右侧的值不为null,则这个表达式的值会被认为是不为null的类型。
即对一个可空值类型使用合并运算并给默认值,会转为基础类型。

引用类型除了string类型外,他们只能接收null作为可选参数默认值。
使用合并运算以方便的为可选引用类型参数在方法内指定默认值。

int Random4(Random? random = null)
{
	random ??= Random.Shared;
	return random.Next(100);
}

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

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

相关文章

K8S:K8S自动化运维容器化(Docker)集群程序

目录 一、K8S概述 1、什么是K8S 2、为什么要用K8S 3、作用及功能 二、K8S的特性 1、弹性伸缩 2、自我修复 3、服务发现和复制均衡 5、自动发布和回滚 6、集中化配置管理和秘钥管理 7、存储编排 8、任务批量处理运行 三、K8S的集群架构 四、K8S的核心组件 1、Mast…

Type-C接口供电小功率设备解决方案

随着Type-C接口的普及&#xff0c;全球使用Type-C接口的设备在稳步上升&#xff0c;因为它更方便&#xff0c;更安全&#xff0c;更环保&#xff0c;如今在生活中可谓是随处可见。 那么在传统的小功率设备大部分还在使用DC圆头供电&#xff0c;虽然成本很低&#xff0c;但是此类…

数字化转型利器,云表无代码“打破”工业软件开发壁垒

近年来&#xff0c;“数字化”概念成为了各行各业的“热词”&#xff0c;作为与信息化程度高度相关的工业软件&#xff0c;在数字化转型中扮演着不可或缺的角色。据 Gartner最新研究数据显示&#xff0c;目前中国工业软件市场规模已经达到了380亿美元&#xff0c;但与发达国家相…

ArcMap最短路径分析和网络数据集的构建

打断相交点 1.单击【编辑器】工具条上的编辑工具。 2.选择要在交叉点处进行分割的线要素。 3.单击【高级编辑】工具条上的打断相交线工具。 4.默认或可输入拓扑容差。 5.单击确定。 结果:所选线在相交处分割为多个新要素。“打断”操作还会移除叠置的线段-例如&#xff0…

HR如何快速提升工作效率?

从招聘到用人管理各个环节&#xff0c;人力资源部门都是公司最重要的职能部门之一&#xff0c;hr的日常工作涉及众多复杂繁琐的内容&#xff0c;比如人员招聘&#xff0c;考核培训等都离不开大量的数据整理和录入操作&#xff0c;但那些和“人”相关的数据信息&#xff0c;经常…

2023.03 青少年机器人技术等级考试理论综合试卷(四级)

2023 年 3 月青少年机器人技术等级考试理论综合试卷&#xff08;四级&#xff09; 一、单选题(共 20 题&#xff0c;共 80 分) 1. Arduino C 语言中&#xff0c;前缀 0x 表示的数制是&#xff1f;&#xff08;D &#xff09; A. 二进制 B. 八进制 C. 十进制 D. 十六进制 2. Ard…

从0学会Spring框架

文章目录 1. 对Spring的理解2. Spring IoC3. DI4. 如何创建一个Spring项目4.1 创建一个Maven项目4.2 添加Spring框架支持4.3 添加启动类 5. 存储Bean对象5.1 添加配置文件5.2 创建Bean对象5.3 注册Bean 6. 获取并使用Bean对象7. 更简单存储Bean对象的方式7.1 前置工作7.2 添加存…

VScode里的终端,Anaconda下的命令提示符和 PowerShell的联系

目录 PowerShell和CMD的区别Anaconda Prompt 和 Anaconda PowerShell Prompt取消默认激活conda中的base环境在conda里设置取消默认激活base环境在VScode里设置取消默认激活base环境手动控制进出base环境 PowerShell和CMD的区别 PowerShell和CMD都是命令行界面工具&#xff0c;…

SuperMap GIS基础产品桌面GIS FAQ集锦(2)

SuperMap GIS基础产品桌面GIS FAQ集锦&#xff08;2&#xff09; 【iDesktop】【10.2.1】【11.0.1】 请问在 iDesktop 桌面端对线数据集进行打断线操作后&#xff0c;打断的线不显示是什么原因呢&#xff1f; 【问题原因】 当时操作的线数据集空间索引存在异常&#xff0c;导致…

C++之数据对齐

数据对齐 • 总说&#xff1a; ○ 对齐方式&#xff1a;表示的是一个类型的对象存放的内存地址应满足的条件 ○ 好处&#xff1a;对齐的数据在读写上有性能优势 ○ 对于不对齐的结构体&#xff0c;编译器会自动补齐以提高CPU的寻址效率 • 数据对齐&#xff1a;(四个函数/描述符…

【shell】shell结程规范与变量

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、shell脚本概述1.Shell脚本应用场景2.Shell的作用3.用户的登录Shell 二、Shell编程规范1.she11脚本的构成2.运行shel1脚本3.重定向与管道操作1.交互式硬件设备2.…

学习CTF一定要知道的网站!快快收藏!

今天在这里给大家介绍一些好用的学习网站&#xff1a; 首先是CTF做题平台&#xff1a; •BUUCTF •攻防世界 •ctf.show •catf1ag.cn •ctfhub.com •ctf.wgpsec.org •ctf-wiki.org •ctftime.org 学习论坛&#xff1a; •https://www.52pojie.cn/ •https://www.freebuf.…

【nvm 安装】使用nvm管理node版本,安装步骤

一、下载nvm 下载链接&#xff1a;Releases coreybutler/nvm-windows GitHub 建议下载安装版的&#xff0c;非安装版还需要额外配置环境变量。 二、安装 注意 &#xff1a; 都在说安装之前需要删除node版本&#xff0c;避免冲突&#xff0c;很听话的我删除了&#xff0c;…

每日学术速递5.4

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.IndoorSim-to-OutdoorReal: Learning to Navigate Outdoors without any Outdoor Experience 标题&#xff1a;IndoorSim-to-OutdoorReal&#xff1a;在没有任何户外经验的情况下学…

Linux系统中ARMv8架构u-boot启动流程分析

目录 ​ 本文基于 armv8 架构来对 u-boot 进行启动流程分析。 1 概述 2 armv8 u-boot的启动 3 u-boot源码整体结构和一些编译配置方式 3.1 编译配置方式 3.2 u-boot源码结构 4 u-boot armv8链接脚本 4.1 u-boot.lds 4.2 u-boot-spl.lds 本文基于 armv8 架构来对 u-bo…

Android LifecycleService

监听Service的生命周期-LifecycleService 为了方便我们对Service生命周期的监听&#xff0c;Android提供了一个名为LifecycleService的类&#xff0c;让该类继承自Service&#xff0c;并实现LifecycleOwner接口。 /*** A Service that is also a {link LifecycleOwner}.*/ pu…

项目实战——获取树形结构

获取树形结构 一、背景介绍二、 思路和方案方案一&#xff1a;使用递归查询的方式并构建树形结构方案二&#xff1a;使用临时表的方式构建树形结构使用临时表的优缺点 三、过程项目案例核心代码 四、总结五、升华 一、背景介绍 我们在开发中时常会遇到需要用到树形结构这种表示…

1分钟学会、3分钟上手、5分钟应用,快速上手责任链框架详解 | 京东云技术团队

作者&#xff1a;京东物流 覃玉杰 1. pie 简介 责任链模式是开发过程中常用的一种设计模式&#xff0c;在SpringMVC、Netty等许多框架中均有实现。我们日常的开发中如果要使用责任链模式&#xff0c;通常需要自己来实现&#xff0c;但自己临时实现的责任链既不通用&#xff0…

解决安装nrm,执行nrm ls时出现的const open=require(‘open’)问题

最开始安装的淘宝镜像源为npm config set registryhttps ://registry.npm.taobao.org/&#xff0c;后来看到镜像源变了&#xff0c;就换了下面的&#xff0c; 下载新的npm淘宝镜像资源包npm config set registry http://registry.npmmirror.com 查看&#xff0c;安装成功&…

【c语言】字符串的基本概念 | 字符串存储原理

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持&#xff01;ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ …