我们先来看一段超简单的使用了这个特性的代码例子:
public static void ShowMessage(string msg = "") { Console.WriteLine("Hello {0}", msg); } static void Main(string[] args) { // 使用默认的 msg = "" ShowMessage(); // 使用指定的参数值 ShowMessage("ghj1976"); // 指定参数值的又一种写法 ShowMessage(msg: "郭红俊"); Console.ReadLine(); }
为什么需要开放命名参数和可选参数呢?
- 这是出于动态语言运行时兼容性的要求。动态语言中存在动态绑定的参数列表,有时候并不是所有的参数值都需要指定(有些语言可能没有重载决策);
- 另外,在一些 COM 互操作时,往往 COM Invoke 的方法参数列表非常的长(例如 ExcelApplication.Save,可能需要 12 个参数),但 COM 暴露的参数的实际值往往为 null,只有很少一部分参数需要指定植,如 ExcelApplication.Save(),可能不需要指定任何参数值,或者仅仅一个值,例如 fileType。为了精简书写的代码,就有着这个特性。
一些注意点:
上面 ShowMessage 函数写法的可选参数(Optional Parameters)必须放在最后,否则将引发 "Optional parameters must appear after all required parameters" 编译错误。
比如这样的写法就是不允许的:
private static void Test2(int x = 0x7b, double y = 45.3, string w) { Console.WriteLine("{0},{1},{2}", s, x, y); }
但是换种写法就可以了:
如下:
private static void Test( [System.Runtime.InteropServices.Optional, System.Runtime.InteropServices.DefaultParameterValue(0x7b)] int x, [System.Runtime.InteropServices.Optional, System.Runtime.InteropServices.DefaultParameterValue(45.3)] double y, string s ) { Console.WriteLine("{0},{1},{2}", s, x, y); }
最初的这种写法在编译时,就是编译生成了 System.Runtime.InteropServices.Optional, System.Runtime.InteropServices.DefaultParameterValue 这样的参数属性。
Optional Parameters 的实质就是:
编译器为可选参数增加了 OptionalAttribute 和 DefaultParameterValueAttribute 特性,以便于引用编译和反射调用时能获取默认值。
至于不用 OptionalAttribute 和 DefaultParameterValueAttribute 特性的写法只不过是种语法糖而已。
当你的方法有多个同一类型的可选参数(optional parameters)时,命名参数(Named parameters)特别有用。如果不用命名参数,编译器就不知道传递的是哪个参数。
仍然是上面的 private static void Test 函数,我们调用时, 就必须这么写:
Test(s: "蝈蝈俊.net");
否则如果我们写成 Test("蝈蝈俊.net"); 就会报错误: No overload for method 'Test' takes 1 arguments
Named Parameters 的实质就是:
命名参数,无非是变相告知参数键值而已,最终编译结果还是按照原有的规则和顺序生成方法调用。这只不过是中语法糖而已。
参考资料:
C# 4.0 新特性 -- 命名参数和可选参数
http://blog.csdn.net/hustorochi/archive/2009/03/20/4007260.aspx
C#特性聚焦:可选和命名参数、COM互操作性
http://www.infoq.com/cn/news/2008/11/CSharp-Optional
C#4.0新特性:可选参数,命名参数,Dynamic
http://www.cnblogs.com/carysun/archive/2009/12/09/CSharp4.html
C# 4.0 - Named and Optional Parameters - Behind the Scenes
http://codebetter.com/blogs/matthew.podwysocki/archive/2008/10/29/c-4-0-named-and-optional-parameters-behind-the-scenes.aspx
[C# 4.0] 4. Named & Optional Parameters
http://www.rainsts.net/article.asp?id=879
C# 4.0 Optional Parameters 和Named Parameters
http://blog.csdn.net/shanyou/archive/2009/10/27/4735970.aspx