《CLR Via C# 第3版》笔记之(十) - 可选参数和可变数量参数
C#中也可以像动态语言那样,定义可选参数和可变数量参数。通过使用可选参数和可变数量参数可以构建更加灵活的函数。
主要内容:
- 可选参数
- 可变数量参数
1. 可选参数
可选参数即调用函数时,传递参数的个数和顺序和定义的不一致。
这样不用重载,也可以实现类似重载的多个版本的函数定义。
示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | using System; namespace cnblog_bowen { public class CLRviaCSharp_10 { static void Main( string [] args) { /* 输出结果 * i=1, s=Z, dt=00010101 00:00:00, g=00000000-0000-0000-0000-000000000000 */ OptionalParams(); /* 输出结果 * i=1, s=ABC, dt=00010101 00:00:00, g=00000000-0000-0000-0000-000000000000 */ OptionalParams(1, "ABC" ); /* 输出结果 当参数顺序与函数定义的不一致时,需要指定参数,如下 dt:xxx * i=1, s=Z, dt=20110704 15:08:46, g=00000000-0000-0000-0000-000000000000 */ OptionalParams(1, dt:DateTime.Now); /* 输出结果 当参数顺序与函数定义的不一致时,需要指定参数,如下 g:xxx * i=1, s=V, dt=00010101 00:00:00, g=eb7d3f73-88e4-4d2d-a5ea-9c0322e3e3bf */ OptionalParams(g:Guid.NewGuid(), s: "V" ); Console.ReadKey( true ); } private static void OptionalParams(Int32 i=1, String s= "Z" , DateTime dt = default (DateTime), Guid g = new Guid()) { Console.WriteLine( "i={0}, s={1}, dt={2}, g={3}" , i, s, dt.ToString( "yyyyMMdd HH:mm:ss" ), g.ToString()); } } } |
在使用可选参数加强了C#的动态性的同时,也需要关注可选参数的一些规则:
- 可以为方法,构造器,有参属性以及委托的参数指定默认值
- 有默认值的参数必须放在没有默认值的参数的后面
- 默认值必须是编译时能确认的常量(如上代码所示,可以使用default和new来定义默认值)
- 用ref和out进行标示的参数不能设置默认值
2. 可变数量参数
可变长参数其实与传递给函数一个数组是类似的。只不过用params标记后,调用函数时更加自然一些。
示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | using System; namespace cnblog_bowen { public class CLRviaCSharp_10 { static void Main( string [] args) { VarargsParams( "price" , 1, 2, 3, 4, 5); Console.ReadKey( true ); } private static void VarargsParams( string s, params Int32[] arr) { Int32 sum = 0; foreach ( var i in arr) { sum += i; } Console.WriteLine( "sum type={0}, sum={1}" , s, sum.ToString()); } } } |
可变数量参数也有一些需要注意的规则:
- params关键字只能用于方法签名的最后一个参数
- 调用params关键字标记的方法和调用普通方法相比,有一些额外的性能损失。
对于以上的第2点,原因如下:
以上面的代码为例,调用函数VarargsParams("price", 1, 2, 3, 4, 5)时,虽然参数是Int32型的,
但还是需要创建一个Int32的数组,需要在堆上分配内存。
没有调用这样的函数快:private static void VarargsParams(string s, Int32 i1, Int32 i2, Int32 i3, Int32 i4, Int32 i5)
由于这个原因,System.String类的Concat方法定义以下几种重载:
public static string Concat(string str0, string str1);
public static string Concat(string str0, string str1, string str2);
public static string Concat(string str0, string str1, string str2, string str3);
public static string Concat(params string[] values);
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 上周热点回顾(1.20-1.26)