《Effective C#》读书笔记——条目10:使用可选参数减少方法重载的数量<C#语言习惯>

  C#4.0 引入了具名参数(MSDN翻译为“命名实参”,个人认为具名参数更形象,可选参数亦是)和可选参数(可选实参)。客户端代码使用具名参数意味着:方法中的参数名称也成为了公有接口的一部分。假如修改公有参数的名称将有可能破坏调用者的代码。这意味着:调用者应该尽可能的避免使用具名参数,而作为API的设计者,也应该避免修改公有货受保护方法中参数的名称。

  当然,并不是说具名参数是一无是处的,它也有自己的适用的场景。具名参数配合可选参数可以简化很多API的调用语法,特别是Microsoft Office的COM API。如下:

1             var wasted = Type.Missing;
2             var wordApp = new Microsoft.Office.Interop.Word.Application();
3             wordApp.Visible = true;
4 
5             Documents docs = wordApp.Documents;
6             Document doc = docs.Add(ref wasted, ref wasted, ref wasted);
7 
8             Range range = doc.Range(0, 0);
9             range.InsertAfter("Testing,testing,testing...");

 

任何的Office Interop应用程序都要使用多次Type.Missing对象,这些毫无意义的代码掩盖了核心的逻辑;这是C#添加可选参数具名参数主要原因。在添加可选参数后在Office API将会为可能使用Type.missing的地方创建默认值,上面的代码可以简化成这样:

1             var wordApp = new Microsoft.Office.Interop.Word.Application();
2             wordApp.Visible = true;
3 
4             Documents docs = wordApp.Documents;
5             Document doc = docs.Add();
6 
7             Range range = doc.Range(0, 0);
8             range.InsertAfter("Testing,testing,testing...");

 

 我们可以看到这个小小的修改增强了代码的可读性。现在假设你想创建一个新的Web页面而不是一个Word文档,而这时Add()方法的最后一个参数,这种情况下可以使用具名参数来指定最后一个参数:

1             var wordApp = new Microsoft.Office.Interop.Word.Application();
2             wordApp.Visible = true;
3             Documents docs = wordApp.Documents;
4 
5             object docType = WdNewDocumentType.wdNewWebPage;
6             Document doc = docs.Add(DocumentType: ref docType);
7 
8             Range range = doc.Range(0, 0);
9             range.InsertAfter("Testing,testing,testing...");

 具名参数的具体含义是:对于那些提供了默认从参数的API,你可以仅提供要用到的那些参数。使用具名参数要比使用多个重载要简单得多。在上面的实例示例中的第六行的ADD方法具名参数使用了ref关键字,在COM场景的编程中使用C#4.0,ref参数也是可选的:因为COM本身都是通过引用传递对象的,所以几乎所有的参数都会以引用的形式传递,即使这些参数不会被调用的方法修改。

  在协作开发中,如果你的代码需要供他人调用,不管你是否同意你的API使用者都可以在任意的地方使用具名参数调用你的方法,所以你必须将参数的名称也当作公有接口的一部分。修改参数名称可能会导致客户代码无法通过编译。

小节:

  对于程序集的第一次发布,可以随意使用可选参数和具名参数,并任意给出你想要提供的重载。但是在后续的发布中,必须为额外的参数创建重载。这样才能保证现有的程序仍然能够正常运行;并且在后续发布中要避免修改参数名称,因为参数名称以及成为了公有接口的一部分。

 

参考资料&进一步阅读

命名实参和可选实参

posted @ 2012-10-07 21:54  gyzhao  阅读(2682)  评论(2编辑  收藏