C#学习 - 参数、拓展方法

传值参数

在声明时不带修饰符的形参就是值参数
一个值参数对应一个局部变量,它的初始值来自该方法调用所提供的相应实参。值参数是实参的副本,对值参数的操作不会影响变量的值

  • 传值参数 - 值类型
internal class Program
{static void Main(string[] args){Tool tool = new Tool();int x = 20;int y = 40;tool.Add(x, y);Console.WriteLine(x);//打印60和20}
}
class Tool
{public void Add(int x, int y){x = x + y;Console.WriteLine(x);}
}
  • 传值参数 - 引用类型,创建新对象
    引用类型的变量存储的值是引用类型实例在堆内存中的地址
    引用类型的变量引用一个实例后传入方法会产生一个副本,此副本存储着一个地址
internal class Program
{static void Main(string[] args){User user = new User() { ID = "111" };Method(user);Console.WriteLine(user.ID);//打印123和111}static void Method(User user){user = new User() { ID = "123" };Console.WriteLine(user.ID);}
}
class User
{public string ID { get; set; }
}
  • 传值参数 - 引用类型,只操作对象,不创建新对象
    通过参数修改值后,其原本的变量所对应的值也会更改
internal class Program
{static void Main(string[] args){User user = new User() { ID = "111" };Method(user);Console.WriteLine("HashCode = {0}, ID = {1}", user.GetHashCode(), user.ID);//此时Hash码和ID都相同}static void Method(User user){user.ID = "123";//没有创建新对象//此为方法的副作用(side-effect),在实际使用中应该避免方法的这些副作用Console.WriteLine("HashCode = {0}, ID = {1}",user.GetHashCode(),user.ID);}
}
class User
{public string ID { get; set; }
}

引用参数

在声明时使用了 ref 修饰符声明的形参,不会创建副本,引用参数所表示的存储位置是在方法调用中作为实参给出的那个变量所表示的存储位置
变量在作为引用参数传递前,必须先明确赋值

  • 引用参数 - 值类型
    在方法内部为参数赋值后,参数获得新值,方法外的变量也获得同样的新值
static void Main(string[] args)
{int x = 10;Method(ref x);Console.WriteLine(x);//打印20
}
static void Method(ref int x)
{x += 10;
}
  • 引用参数 - 引用类型,创建新对象
    引用类型的变量传进方法后,引用参数和变量指向同一个地址,地址中存储的是另一个地址——变量所指向的对象在堆内存中的地址
    在方法体中为参数赋了新值后,变量会指向一个新创建的对象
internal class Program
{static void Main(string[] args){User user = new User() { ID = "111" };Console.WriteLine("HashCode = {0}, ID = {1}", user.GetHashCode(), user.ID);Method(ref user);Console.WriteLine("HashCode = {0}, ID = {1}", user.GetHashCode(), user.ID);//打印三行//第一次打印与后面不同//方法调用后的两次的Hash码和ID都相同}static void Method(ref User user){	//Hash码变化后是因为方法体中new了一个新值user = new User() { ID = "123" };Console.WriteLine("HashCode = {0}, ID = {1}", user.GetHashCode(), user.ID);}
}
class User
{public string ID { get; set; }
}
  • 引用参数 - 引用类型,不创建新对象,只改变对象值
    此时与传值参数在效果上一样,但机理不同
    Hash码不改变,只有对象的值会改变
    传值参数中:参数和变量所指向的内存地址不同
    引用参数中:参数和变量所指向的内存地址相同
internal class Program
{static void Main(string[] args){User user = new User() { ID = "111" };Console.WriteLine("HashCode = {0}, ID = {1}", user.GetHashCode(), user.ID);Method(ref user);Console.WriteLine("HashCode = {0}, ID = {1}", user.GetHashCode(), user.ID);//三次打印出来后Hash码都相同//方法调用后,对象(ID)值改变}static void Method(ref User user){user.ID = "123";Console.WriteLine("HashCode = {0}, ID = {1}", user.GetHashCode(), user.ID);}
}
class User
{public string ID { get; set; }
}

输出参数

用 out 修饰符声明的参数,输出参数不创建新的存储位置
变量在作为输出参数传递前,不需要赋值
在方法返回时,该方法的每一个输出参数都必须明确赋值
传值参数:利用副作用修改值
输出参数:利用副作用向外输出

  • 输出参数 - 值类型
    参数和变量指向的地址是同一个
    方法体中为参数赋值后,变量也会获得相同的新值
    输出参数并不需要创建变量的副本
Console.WriteLine("Input Num1:>");
string arg1 = Console.ReadLine();
double x = 0;
bool b1 = double.TryParse(arg1, out x);
//TryParse方法返回一个bool类型的值
//将string类型的值转换为double类型的值并输出
if(b1 == false)
{Console.WriteLine("Input error");return;
}
Console.WriteLine("Input Num2:>");
string arg2 = Console.ReadLine();
double y = 0;
bool b2 = double.TryParse(arg2, out y);
if (b2 == false)
{Console.WriteLine("Input error");return;
}
Console.WriteLine("{0} + {1} = {2}", x, y, x + y);
  • 输出参数 - 引用类型
    引用类型以输出参数的形式传入方法,在方法体中的参数赋值后,变量会指向一个新地址,指向的是新创建的对象在堆内存上的地址
internal class Program
{static void Main(string[] args){User user = null;bool b = UserFactory.Create("JACK", 1233431, out user);if(b==true){Console.WriteLine("User:> {0}\nCode:> {1}", user.ID, user.Code);}}
}
class User
{public string ID { get; set; }public int Code { get; set; }
}
class UserFactory//创建User
{public static bool Create(string userID, int userCode, out User result){result = null;if (string.IsNullOrEmpty(userID)){return false;}result = new User() { ID = userID, Code = userCode };return true;}
}

数组参数

声明时由params修饰
未使用数组参数:

static void Main(string[] args)
{int[] intArray = { 1, 2, 3 };int result = CalculateSum(intArray);Console.WriteLine(result);
}
static int CalculateSum(int[] nums)
{int sum = 0;foreach (var i in nums) {sum += i;}return sum;
}

使用数组参数:

static void Main(string[] args)
{int result = CalculateSum(1, 2, 3);//无须声明一个数组Console.WriteLine(result);
}
static int CalculateSum(params int[] nums)
{						//数组参数int sum = 0;foreach (var i in nums) {sum += i;}return sum;
}

数组参数一些例子:

  • Console.WriteLine
int x = 100;
int y = 200;
int z = x + y;
Console.WriteLine("{0} + {1} = {2}", x, y, z);
  • Split 方法
string str = " USSR; MOS, RS";
string[] result = str.Split(';', ',');//Split可以分割字符串
foreach (string area in result)
{Console.WriteLine(area);
}

注意:在一个方法的参数列表中,只能有一个参数由params修饰,且此参数为参数列表中最后一个参数

具名参数

调用方法时,传入的参数带有名字
不具名调用:

static void Main(string[] args)
{Print("Jack", 18);
}
static void Print(string name, int age)
{Console.WriteLine("{0} is {1} years ago", name, age);
}

具名调用:

static void Main(string[] args)
{Print(name: "Jack", age: 18);
}
static void Print(string name, int age)
{Console.WriteLine("{0} is {1} years ago", name, age);
}

优点:

  • 可以提高代码可读性
  • 传入参数的顺序不再受到参数列表的限制

可选参数

在调用某个方法时,此参数可传入也可以不传入
当不写时,此参数默认获得声明时的值

static void Main(string[] args)
{Print(name: "John");
}
static void Print(string name = "Jack", int age = 18)
{Console.WriteLine("{0} is {1} years ago", name, age);
}

扩展方法(this参数)

double pi = 3.1415926;
double a = Math.Round(pi, 2);
//Round方法第一个值是对谁四舍五入
//第二个值是精确到第几位
Console.WriteLine(a);

double类型没有Round方法,只能依靠Math
而扩展方法可以使用double类型调用Round方法

internal class Program
{static void Main(string[] args){double pi = 3.1415926;double a = pi.Round(2);//.前面的pi就是第一个参数,只输入第二个参数Console.WriteLine(a);}
}
static class DoubleExtension
{public static double Round(this double input, int digits){double result = Math.Round(input, digits);return result;}
}

注意:

  • 方法必须是公有的、静态的(被public static修饰)
  • 必须是参数列表中的第一个,由this修饰
  • 必须由一个静态类(一般类名为SomeTypeExtension)来统一收纳SomeType类型的扩展方法

LINQ方法

写一个能接收集合类型的参数的方法,判断集合中的值是否都大于10
未使用LINQ方法:

static void Main(string[] args)
{List<int> myList = new List<int>() { 10, 20, 30 };bool b = ItemBiggerTen(myList);Console.WriteLine(b);
}
//上为方法调用,下为方法
static bool ItemBiggerTen(List<int> intList)
{foreach (int i in intList){if (i <= 10){return false;}}return true;
}

使用LINQ方法:

static void Main(string[] args)
{List<int> myList = new List<int>() { 10, 20, 30 };bool b = myList.All(i => i > 10);//查看所有元素是否都大于10//All方法可以接收委托类型的参数Console.WriteLine(b);
}

上段代码中的 All() 方法就是扩展方法,不属于List类,而属于Enumerable这个静态类

各种参数使用场景

  • 传值参数:参数的默认传递方法
  • 输出参数:用于除返回值之外还需要输出的场景
  • 引用参数:用于需要修改实际参数值的场景
  • 数组参数:用于简化方法的调用
  • 具名参数:提高可读性,解除参数传入顺序的限制
  • 可选参数:参数拥有默认值
  • 扩展参数:为目标数据类型“追加”方法

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

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

相关文章

C++ 使用堆栈解决回文匹配问题

题目&#xff1a;设称正读和反读都相同的字符序列为“回文”&#xff0c;例如&#xff0c;“abba“和“abccba”是“回文”&#xff0c;“abcde”和“ababab”则不是“回文“&#xff0c;试写一个算法&#xff0c;判别读入的一个以为结束符的字符序列是否是“回文”。 主要思想…

如何读懂深度学习python项目,以`Multi-label learning from single positive label`为例

Paper : Multi-label learning from single positive label Code 先读一读README.md 可能有意想不到的收获&#xff1b; 实验环境设置要仔细看哦&#xff01; 读论文 如何读论文&#xff0c;Readpaper经典十问 &#xff08;可能在我博客里有写&#xff09; How to read a …

@JsonFormat 注解的使用

SpringBoot 中的 JsonFormat 注解 1. 引言2. 简介3. 使用①引入依赖②添加注解 1. 引言 在前后端交互过程当中&#xff0c;往往需要后端返回前端日期类型数据&#xff0c;在将数据返回给前端的时候&#xff0c;可能会需要对日期类型进行格式化&#xff1b; 为更便捷的返回需要…

html获取网络数据,列表展示 一

html获取网络数据&#xff0c;列表展示 js遍历json数组中的json对象 image.png || - 判断数据是否为空&#xff0c;为空就显示 - <!DOCTYPE html> <html><head><meta charset"utf-8"><title>网页列表</title></head><b…

WordPress恢复时候遇到的几个问题

1&#xff0c;一键安装 LAMP 最好是选择 CentOS 这种成熟的系统&#xff0c;最开始用 Alibaba Linux 报了好几个错&#xff0c;懒得折腾&#xff0c;最后重置镜像了。 https://lnmp.org/ wget https://soft.lnmp.com/lnmp/lnmp2.0.tar.gz -O lnmp2.0.tar.gz && tar z…

省钱兄短剧短视频视频滑动播放模块源码支持微信小程序h5安卓IOS

# 开源说明 开源省钱兄短剧系统的播放视频模块&#xff08;写了测试弄了好久才弄出来、最核心的模块、已经实战了&#xff09;&#xff0c;使用uniapp技术&#xff0c;提供学习使用&#xff0c;支持IOSAndroidH5微信小程序&#xff0c;使用Hbuilder导入即可运行 #注意&#xff…

JavaScript从入门到精通系列第二十六篇:详解JavaScript中的Math对象

大神链接&#xff1a;作者有幸结识技术大神孙哥为好友&#xff0c;获益匪浅。现在把孙哥视频分享给大家。 孙哥连接&#xff1a;孙哥个人主页 作者简介&#xff1a;一个颜值99分&#xff0c;只比孙哥差一点的程序员 本专栏简介&#xff1a;话不多说&#xff0c;让我们一起干翻J…

ES的三种分页的选择

一、ES的三种分页的选择 es实现分页查询&#xff0c;在ES中有三种方式可以实现分页&#xff1a;fromsize、scroll、search_after 1、fromsize 分页 原理&#xff1a; 假设取的页数较大时(深分页)&#xff0c;如请求第20页&#xff0c;Elasticsearch不得不取出所有分片上的第…

无人机真机搭建问题记录文档(待续)

搭建问题 问题1 高飞课程中的飞控停产&#xff0c;更换飞控&#xff08;pixhawx 6c&#xff09;出现如下问题 1、飞控太大造成安装机载电脑的碳板上的孔被挡住。 2、课程提供的飞控固件&#xff0c;与更换的飞控不匹配 解决办法 1、现在的无人机碳板上只安装三个螺纹孔&…

pytorch 笔记:index_select

1 基本使用方法 index_select 是 PyTorch 中的一个非常有用的函数&#xff0c;允许从给定的维度中选择指定索引的张量值 torch.index_select(input, dim, index, outNone) -> Tensorinput从中选择数据的源张量dim从中选择数据的维度index 一个 1D 张量&#xff0c;包含你想…

GPS学习(一):在ROS2中将GPS经纬度数据转换为机器人ENU坐标系,在RVIZ中显示坐标轨迹

文章目录 一、GPS模块介绍二、坐标转换转换原理参数解释&#xff1a; 增加回调函数效果演示 本文记录在Ubuntu22.04-Humbel中使用NMEA协议GPS模块的过程&#xff0c;使用国产ROS开发板鲁班猫(LubanCat )进行调试。 一、GPS模块介绍 在淘宝找了款性价比较高的轮趣科技GPS北斗双…

Linux 远程桌面软件

为您的 IT 管理员配备最好的 Linux 远程桌面软件至关重要。原因如下&#xff1f;Linux 是一个开源和免费的操作系统&#xff0c;它提供了一个非常灵活和可定制的软件内核。由于其开源性质&#xff0c;Linux 被认为是市场上最安全的操作系统之一&#xff0c;它拥有一个全球用户社…

关于readline方法使用的一个中文乱码引发的思考

故事起源于这段代码&#xff0c;我想给一个本地地址然后去读取文件内容&#xff0c;然后使用了reader.readLine();方法&#xff0c;但是本地没有任何报错&#xff0c;但是线上中文乱码导致直接报错了。 BufferedReader reader;try {reader new BufferedReader(new FileReader(…

Qt 中model/View 架构 详解,以及案例实现相薄功能

model/View 架构 导读 ​ 我们的系统需要显示大量数据,比如从数据库中读取数据,以自己的方式显示在自己的应用程序的界面中。早期的 Qt 要实现这个功能,需要定义一个组件,在这个组件中保存一个数据对象,比如一个列表。我们对这个列表进行查找、插入等的操作,或者把修改…

PHP自定义文件缓存实现

文件缓存&#xff1a;可以将PHP脚本的执行结果缓存到文件中。当一个PHP脚本被请求时&#xff0c;先查看是否存在缓存文件&#xff0c;如果存在且未过期&#xff0c;则直接读取缓存文件内容返回给客户端&#xff0c;而无需执行脚本 1、文件缓存写法一&#xff0c;每个文件缓存一…

【项目实训】汽车租贷系统(完整代码)

文章目录 1.实验目标2.实验设计3.完整代码4.具体分析5.实验结果附:系列文章1.实验目标 本实验旨在设计和实现一个汽车租赁系统,供客户使用。该系统能够根据客户的选择自动计算租金、租车日期、注意事项以及优惠金额等内容,并提供相应的服务和提示。 2.实验设计 2.1 类的设…

语音信号处理给音乐信号增加房间混响效果

语音信号处理给音乐信号增加房间混响效果 是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务 1 源码布局 2 源文件与音频文件和生成文件 3 编译方法

vue-router学习(三) --- 导航守卫

文章目录 全局导航守卫路由独享导航守卫组件内的守卫完整的导航解析流程loadingBar 案例 全局导航守卫 beforeEachbeforeResolveafterEach 路由导航守卫 beforeEnter 组件导航守卫 beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave 全局导航守卫 当一个导航触发时&#x…

「Qt中文教程指南」如何创建基于Qt Widget的应用程序(四)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文描述了如何使用…

点云配准--对称式ICP

对称式ICP 写在前面的话 针对于局部平面不完美的情况&#xff0c;提出了一种对称式ICP目标函数&#xff0c;相较于传统的ICP方法&#xff0c;增大了收敛域&#xff0c;提高了收敛速度。论文理论说明不甚清楚&#xff0c;实验较少&#xff0c;但代码开源。 理论 对称目标函数…