首页 > 编程语言 >刘铁猛C#学习笔记12 参数种类详解

刘铁猛C#学习笔记12 参数种类详解

时间:2024-02-23 23:11:06浏览次数:29  
标签:输出 12 C# 刘铁猛 参数 引用 params 实参 方法

一、值参数(传值参数、值传递)

参数的种类为值参数,而非参数数据类型为值类型

1.值类型的传值参数

类似一个新声明的局部变量,或传进来的实参的一个副本 可以在方法体内重现赋值,但其在方法体内被赋值时,不会影响传进来的本体  

2.引用类型的传值参数

引用类型变量存储的是实例在堆内存中的地址

(1)在方法中给形参赋了新值

引用变量作为实参传进方法后会产生一个副本(形参),形参里存的也是实参指向的对象的地址 也就是说,一开始,引用形参引用实参,指向的是同一个实例对象 但如果在方法体内对形参进行了赋值形参指向的会是赋给他的新对象的地址 但不会对方法外实参产生任何影响,实参仍然指向原对象地址 (实际编程中,这种操作是非常少见的)  

(2)不赋新值,只操作对象

由于形参和实参指向的都是存在堆内存中的同一个对象!!!!!!! 所以对象内的成员值会被改变 所以在方法内使用值参数,当参数为引用类型时,也可能导致方法外的东西发生改变! 打破了值参不会影响方法外事物的神话   这种使用在实际开发中比较少见 一般将这种方法修改了参数引用对象的值的操作,称作某个方法的副作用(side-effect) 一般来说方法还是通过返回值来发挥主作用,副作用的情况要尽量避免    

二、引用参数ref(引用传递)

参数的种类为引用参数,而非参数数据类型为引用类型 引用参数不会为传进来的实参创建副本 也就是说,引用参数直接指向实际参数的变量存储位置 关键:形参与实参完全统一为一体,参数在方法内与方法外完全一致,患难与共 形实统一,内外统一 作为调用方法时用引用传递传进来的变量,在此之前一定要有实际的赋值 且调用时在引用参数前必须加上ref关键字  

1.值类型的引用参数

参数并非传进来的参数的副本,而是存在内存中同一个地址的同一个值 当引用传递的参数在方法内被赋了新值时,方法外的变量也会随之一起改变 (与C、C++中的指针有关?) 带有引用参数的方法,是用ref关键字,来显式地强调在有意地利用函数的副作用改变参数的值 在声明和调用时都要写上ref  

2.引用类型的引用参数

在方法体内对引用类型的引用参数重新赋值时,方法内的形参指向了赋给他的新对象 由于对应引用传递,形参与实参是一体的,所以方法外的实参变量,也跟着指向了这个新对象 如上实验结果表明,在方法内赋值后,方法外的变量一同指向了方法内创建的新对象 方法外实参与方法内形参,哈希识别码的值完全一致,二者指向的是同一个实例对象,且在方法内被赋值时会一同改变   若使用引用类型引用参数,但不为参数赋新值,只操作实例对象的成员 这样使用的效果和引用类型值参数是完全一样的,只是内存机理不一样 实验结果发现,不对引用类型的参数赋新值,只操作字段 哈希识别码没有改变,方法内外参数指向的实例对象都没有改变,只有实例对象的成员字段被改变了 效果上与值传递的引用变量一样,但内存机理不同 值传递创建了实际参数的副本,引用传递没有创建副本 但值传递参数的本体和副本,存储的都是同一个实例在堆内存中的地址,相当于两个变量存一个地址 引用参数没有创建副本,是一个变量存一个地址    

三、输出参数out(输出形参)

方法作为数据的加工厂,产物只有一个返回值 那么如果希望一个方法有多个产物,就要用输出参数 也是一种对方法副作用的利用,利用输出参数,获得除返回值之外的额外输出   输出参数和引用参数一样,不为参数创建副本 引用参数在传进方法之前要先赋值 输出参数在传进方法之前不用赋值  

1.值类型的输出参数

与引用传递类似由于输出参数不创建副本,所以给参数赋值,方法体外的变量也会同时获得新值  

C#已有示例:

规则: 1.输出参数在方法体里必须被赋值 2.输出参数名需要是一个已声明的变量? 3.在有输出参数的方法中,如果方法执行失败,作为输出参数传进来的变量原本的值可能会被覆盖而丢失。所以作为输出参数的已有变量,一般不需要赋初始值  

2.引用类型的输出参数

与引用传递类似,方法内的参数被赋新值,指向一个新对象后,方法外作为输出参数的变量也会一同被改变,指向新对象   使用例子:方法带有尝试性质,不确定是否真的能执行 就可以用返回值装一个bool变量,用来判断是否能够执行 用输出参数out来装方法的一个或多个输出值 用来尝试性的将信息灌装进实例对象中  

四、params特殊数组参数

必须是形参列表的最后一个,用params修饰  

示例:数组求和函数

1.不使用params的情况

不使用params修饰符的情况下,也可以用数组名当作函数的参数 声明时不用修饰,只需要把形参类型写为带索引器[ ]的 调用:调用时参数直接写数组名,不用加索引器[ ]  

2.使用params的情况

声明功能声明时使用了params修饰符,与不使用没有什么区别 但是调用方法时多了一个选择,可以不提前声明一个数组来作为参数,可以直接把想作为参数的数组的元素直接列在方法的参数列表()中,编译时会自动创建一个object类型的数组,将元素放进去作为参数传入方法 当参数类型为params数组参数时,调用时就可以输入任意个数的参数!!!!! 非常方便  

C#已有示例:天天用的打印方法

当参数类型为params数组参数时,调用时可以输入任意个数的参数 所以打印方法可以一次打印任意个数的字符串  

C#已有示例2:字符串分割方法

str.Split方法的参数是一个params字符串数组,参数列表中,依次写上了各个分隔符,可以写任意个数的参数,返回值也是一个字符串数组,在按顺序用分隔符切割后,方法返回切割好的各个字符串  

重要注意事项

由于params数组参数调用时可写无限个参数的特性 一个方法只能有一个params数组参数! params数组参数必须是方法的参数列表中的最后一个!  

五、具名参数

是一种调用方法时的参数使用方法   参数带有名字,参数的位置不再受约束 先正常声明一个方法 调用时写上参数的名字+冒号:,参数的位置就可以不再受参数列表顺序的约束 而且这样写上参数名字的调用方法,可以  

六、可选参数

声明时参数具有 声明时给参数加上 在调用时就会显示参数是可选的 不写参数就会按声明时写的默认值去执行 编程规范:不推荐使用可选参数(不如用重载?)  

七、扩展方法(this参数)

用于给一个已有的、不方便修改源码的类型,添加追加方法 扩展方法必须是public static的, 编程规范:并且必须放在一个静态类(名字一般为SomeTypeExtension)中 由this修饰的参数必须是参数列表中的第一个   C#的很多强大的功能都是基于扩展方法,包括 这里涉及委托和拉姆达表达式,以后再详细学习 All方法并不在List的定义中,这是一个扩展方法,写在Linq命名空间旗下的Enumerable类中   Linq命名空间中包括: 包括 All:查询集合中是否所有元素都满足(倒A标志) Any:查询集合汇总是否有至少一个元素满足(反E存在标志) Average:求集合内元素的平均值 (大概里面有很多关于集合的扩展方法)  

总结

 

标签:输出,12,C#,刘铁猛,参数,引用,params,实参,方法
From: https://www.cnblogs.com/jk-2048/p/18030534

相关文章

  • 代码随想录算法训练营day03 | leetcode 203. 移除链表元素、707. 设计链表、206. 反转
    目录题目链接:203.移除链表元素-简单题目链接:707.设计链表-中等题目链接:206.反转链表-简单题目链接:203.移除链表元素-简单题目描述:给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val==val的节点,并返回新的头节点。示例1:输入:head=[1,2,6......
  • 恢复VCPkg(2023-01-27)中Vtk[Qt]的默认依赖为Qt5
    通过查看vtk的更新的日志已于2023-01-27将默认依赖的Qt的版本由5更新到6gitlog--.\ports\vtkcommit27fb19bdcc1f6ddb1261cffb5372724ac1d63a93Author:LilyWang<[email protected]>Date:2023-08-23[manyports]FixURLSofdownlo......
  • P9370 APIO2023 cyberland
    题面:https://www.luogu.com.cn/problem/P9370显然只有从\(0\)出发不经过\(H\)能到达的点是有用的。首先,考虑跑多源最短路,将\(arr=0\)的点都作为源点(当然\(0\)也是源点)。不难发现这样转化后,这些点即可视作\(arr=1\)。对于\(arr=2\)的点,由于能使用除以二技能的次数很......
  • POLIR-Economics-西方经济学学习经验(转发)
    原文:https://bbs.pinggu.org/thread-894259-1-1.htmlhttps://bbs.pinggu.org/forum-47-1.html西方经济学属于纯理论性的学科,它所包括的知识也基本上是比较模式化的,也就是说,相对于政治经济学它联系实际的东西比较少,能与实际联系起来的地方主要是宏观部分的财政政策、货币政策、通......
  • LGC引理
    LGV引理内容(不会证明)\(\omega(P)\)表示P这条路径上所有边的边权之积。(路径计数时,可以将边权都设为1)(事实上,边权可以为生成函数)e(u,v)表示u到v的每一条路径P的$\omega(P)$之和,即$e(u,v)=\sum\limits_{P:u\rightarrowv}\omega(P)$。起点集合\(A\),是有向无......
  • 线段树分治&cdq分治&整体二分
    preface感觉三种分治算法容易搞混并不容易区分它们使用的场景和题目(虽然有些题目根据性质可以使用多种分治),所以还是要归纳一下线段树分治Part1主要是处理一类带有撤回的问题,也就是一次修改只对一段区间生效(这里的区间指的是时间)即区间修改,单点查询流程大致是把区间修改挂在......
  • P10139 [USACO24JAN] Nap Sort G 题解
    DescriptionBessie正在尝试使用她自己的排序算法对一个整数数组进行排序。她有一堆共\(N\)(\(1\leN\le2\cdot10^5\))个整数\(a_1,a_2,\ldots,a_N\)(\(1\lea_i\le10^{11}\)),她将会按排序顺序将这些数放入一个单独的数组中。她反复查找这堆数中的最小数,将其删除,同时将其添加到......
  • Edu-English-Phonetic-IPA:国际音标发音学:英语音标的学习神器,终于找到
    https://mp.weixin.qq.com/s?__biz=MzU3NTIzOTA5OA==&mid=2247493736&idx=1&sn=8ed10241adeaa148ee3053f5db94214e&chksm=fd248ebdca5307abf32a39eed20bb83818e00692a87298d3b1c2d2cb7b2d6572df0c0301fe7d&scene=27英语音标的学习神器,终于找到音标是记录语言的符号,对音标的正确......
  • 如何学习PYTHON(python和c++哪个难学)
    1.如何学习PYTHONPython是一门简单易学的编程语言,但想要真正掌握它需要花费不少时间和精力。我的建议是先从Python基础开始学习,掌握基本语法和常见数据结构,再逐步深入学习高级特性和应用场景。 在学习Python的过程中,https://www.fuligou8.com/noking/4006.html我们可以通过阅......
  • 循环掌控:深入理解C语言循环结构,高效实现重复性任务
    ✨✨欢迎大家来到贝蒂大讲堂✨✨......