写这一篇的原由是想要经过新增默认参数来代替之前的方法,结果发现尽管在调用时写起来同样,实际上也没有被当作一样的方法,两个方法大体以下:html
// 先前的方法-删除 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)的角度去看一下命令行
借助一个简单的例子,先用经常使用的反编译工具看一下code
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里面反编译看下htm
重点对比看下 TestMethodWithDefaultParam 这个方法的调用,能够发现虽然咱们没有传入第二个参数,可是因为默认参数的存在,编译器自动帮咱们补上了一个参数,而 TestMethod 方法则明显是调用第一个没有默认参数的,有默认参数的 TestMethod 方法被忽略了blog
经过ILSpy咱们简单的看到调用时两个方法的区别,可是默认参数的实现状况咱们还不是很清楚,因此能够再经过VisualStudio自带的IL反汇编程序ildasm看一下,使用VS的命令行工具输入 ildasm 打开程序,而后打开咱们的控制台程序的exe文件get
经过这个目录咱们能够明确的看到,两个TestMethod方法的参数形式,默认参数的方式只是让咱们在调用的时候能够省略参数,而在程序中这个方法仍然具备这个参数,当两个同名的方法一块儿存在是就至关于方法的重载,调用时传入对应的参数即调用对应的方法编译器
这时咱们打开有默认参数的方法,能够看到在IL的形式下,默认参数前面有个[opt]的标识,表明着Optional,即“可选的”,这是C#的一个特性标签——OptionalAttribute,经过OptionalAttribute和DefaultParameterValueAttribute这两个特性也就实现了C#的默认参数,这方面已经有相关的博文,能够参考谈谈C# 4.0新特性“缺省参数”的实现string