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使用者都可以在任意的地方使用具名參數調用你的方法,所以你必須將參數的名稱也當作公有接口的一部分。修改參數名稱可能會導致客戶代碼無法通過編譯。
小節:
對於程序集的第一次發布,可以隨意使用可選參數和具名參數,並任意給出你想要提供的重載。但是在后續的發布中,必須為額外的參數創建重載。這樣才能保證現有的程序仍然能夠正常運行;並且在后續發布中要避免修改參數名稱,因為參數名稱以及成為了公有接口的一部分。