C#默认参数原理探究
起因
写这一篇的起因是想要通过新增默认参数来代替以前的方法,结果发现尽管在调用时写起来一样,实际上也没有被当做同样的方法,两个方法大致如下:
// 先前的方法-删除
private static string TestMethod(string first)
{
return first;
}
// 新增的同名方法
private static string TestMethod(string first, string second = "2")
{
return second;
}
上述两种方法都可以通过 TestMethod("1"); 调用,所以最开始误以为两个方法的调用是等价的,但是实际使用中通过DLL引用的方式会提示找不到方法,这里就出现了问题。
首先我们可以进行一个尝试,会发现这两个方法可以同时存在,还是上面的例子,这时再通过 TestMethod("1"); 调用会发现返回的结果是“1”,也就是第一个没有默认参数的方法
到这里为止,暂时还不太清楚原理,但是可以感觉到调用时程序中的写法可能是区别的,这时候我们可以再深入一点,通过中间语言IL(Intermediate Language)的角度去看一下
ILSpy
借助一个简单的例子,先用常用的反编译工具看一下
static void Main(string[] args)
{
Console.WriteLine(TestMethod("1"));
Console.ReadKey();
TestMethodWithDefaultParam(string.Empty);
}
private static string TestMethod(string first)
{
return first;
}
private static string TestMethod(string first, string second = "2")
{
return second;
}
private static void TestMethodWithDefaultParam(string first, string second = "2")
{
}
把编译的好的程序放到ILSpy里面反编译看下
重点对比看下 TestMethodWithDefaultParam 这个方法的调用,可以发现虽然我们没有传入第二个参数,但是由于默认参数的存在,编译器自动帮我们补上了一个参数,而 TestMethod 方法则明显是调用第一个没有默认参数的,有默认参数的 TestMethod 方法被忽略了
ildasm
通过ILSpy我们简单的看到调用时两个方法的区别,但是默认参数的实现情况我们还不是很清楚,所以可以再通过VisualStudio自带的IL反汇编程序ildasm看一下,使用VS的命令行工具输入 ildasm 打开程序,然后打开我们的控制台程序的exe文件
通过这个目录我们可以明确的看到,两个TestMethod方法的参数形式,默认参数的方式只是让我们在调用的时候可以省略参数,而在程序中这个方法仍然具有这个参数,当两个同名的方法一起存在是就相当于方法的重载,调用时传入对应的参数即调用对应的方法
这时我们打开有默认参数的方法,可以看到在IL的形式下,默认参数前面有个[opt]的标识,代表着Optional,即“可选的”,这是C#的一个特性标签——OptionalAttribute,通过OptionalAttribute和DefaultParameterValueAttribute这两个特性也就实现了C#的默认参数,这方面已经有相关的博文,可以参考谈谈C# 4.0新特性“缺省参数”的实现
C#默认参数原理探究的更多相关文章
- 【转】Python函数默认参数陷阱
[转]Python函数默认参数陷阱 阅读目录 可变对象与不可变对象 函数默认参数陷阱 默认参数原理 避免 修饰器方法 扩展 参考 请看如下一段程序: def extend_list(v, li=[]) ...
- Python面试题目之Python函数默认参数陷阱
请看如下一段程序: def extend_list(v, li=[]): li.append(v) return li list1 = extend_list(10) list2 = extend_l ...
- 弱类型变量原理探究(转载 http://www.csdn.net/article/2014-09-15/2821685-exploring-of-the-php)
N首页> 云计算 [问底]王帅:深入PHP内核(一)——弱类型变量原理探究 发表于2014-09-19 09:00| 13055次阅读| 来源CSDN| 36 条评论| 作者王帅 问底PHP王帅 ...
- SpringBoot:运行原理探究
西部开源-秦疆老师:基于SpringBoot 2.1.6 的博客教程 秦老师交流Q群号: 664386224 未授权禁止转载!编辑不易 , 转发请注明出处!防君子不防小人,共勉! SpringBoot ...
- ThreadPoolExcutor 原理探究
概论 线程池(英语:thread pool):一种线程使用模式.线程过多会带来调度开销,进而影响缓存局部性和整体性能.而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务.这避免了在处理短时间 ...
- [原] KVM 虚拟化原理探究(5)— 网络IO虚拟化
KVM 虚拟化原理探究(5)- 网络IO虚拟化 标签(空格分隔): KVM IO 虚拟化简介 前面的文章介绍了KVM的启动过程,CPU虚拟化,内存虚拟化原理.作为一个完整的风诺依曼计算机系统,必然有输 ...
- [原] KVM 虚拟化原理探究(3)— CPU 虚拟化
KVM 虚拟化原理探究(3)- CPU 虚拟化 标签(空格分隔): KVM [TOC] CPU 虚拟化简介 上一篇文章笼统的介绍了一个虚拟机的诞生过程,从demo中也可以看到,运行一个虚拟机再也不需要 ...
- [原] KVM 虚拟化原理探究(2)— QEMU启动过程
KVM 虚拟化原理探究- QEMU启动过程 标签(空格分隔): KVM [TOC] 虚拟机启动过程 第一步,获取到kvm句柄 kvmfd = open("/dev/kvm", O_ ...
- nmap参数原理抓包分析
nmap参数原理抓包分析 实验环境: Nmap7.70 实验步骤: 1.主机发现 2.端口扫描 3.服务版本探测 一.主机发现 主机发现,如果主机活跃,扫描1000个常用的tcp端口 1.Nmap i ...
随机推荐
- Dubbo(一) —— 基础知识和项目搭建
一.分布式基础理论 1.什么是分布式系统? <分布式系统原理与范型>定义: “分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统” 分布式系统(distribut ...
- 使用dotnet build时复制引用dll到生成目录
默认配置下dotnet build只会输出项目代码的dll,依赖用的是dotnet缓存中的dll,只有dotnet publish才会把依赖的dll一起输出到生成目录. 在项目csproj文件中添加以 ...
- Lucene 02 - Lucene的入门程序(Java API的简单使用)
目录 1 准备环境 2 准备数据 3 创建工程 3.1 创建Maven Project(打包方式选jar即可) 3.2 配置pom.xml, 导入依赖 4 编写基础代码 4.1 编写图书POJO 4. ...
- 自定义微信小程序导航(兼容各种手机)
详细代码请见github,请点击地址,其中有原生小程序的实现,也有wepy版本的实现 了解小程序默认导航 如上图所示,微信导航分为两部分,第一个部分为statusBarHeight,刘海屏手机(iPh ...
- Mac终端工具item2实现覆盖在屏幕上透明效果
1.去官网安装item2: https://www.iterm2.com/downloads.html 2.打开preferences 3.到keys配置: 4.点击上图展示的Create a Ded ...
- Mybatis入门之增删改查
Mybatis入门之增删改查 Mybatis如果操作成功,但是数据库没有更新那就是得添加事务了.(增删改都要添加)----- 浪费了我40多分钟怀疑人生后来去百度... 导入包: 引入配置文件: sq ...
- 2018/12/21:Date类
1.Date类 getDate()返回一个月的某一天 1-31 getDay()返回一周的某一天 getFullyear()返回四位数的年份 getMonth()返回月份 比实际情况小 1 0代表1月 ...
- CA证书理解?CA证书的作用?
CA证书顾名思义就是由CA(Certification Authority)机构发布的数字证书.要对CA证书完全理解及其作用,首先要理解SSL.SSL(security sockets layer,安 ...
- WingMoney APP逆向,实现自动话费充值
主要难点,获取JWT内加密的token. 因为是打算使用写成c# winform版本的.所以折腾了很久.刚开始直接改写成c#版本始终有问题.最后决定先上eclipse,先使用java把数据读取出来. ...
- es6 Moduel 默认名与非默认名
export default default 本质是将后面变量(值)赋给 default,然后以default名称输出. import 在获取default变量时,写在大括号的外面 ,可自定义名称. ...