命名參數允許調用者通過提供參數的名稱來為其賦值這樣參數的位置就不在重要了可選參數允許在定義時為某些參數賦值在調用時可以忽略這些可選的參數命名參數和可選參數可以應用在方法索引器構造函數和委托命名參數和可選參數與dynamic類型結合在一起使用可以方便的訪諸如Office自動化API之類的COM API
命名參數
命名參數的語法為
參數名稱:參數值參數名稱:參數值…
例如以下代碼
static void Main(string[] args)
{
CreateUser(password:adminpasswordname:admin);
}
static void CreateUser(string name string password)
{
ConsoleWriteLine(name:{}password:{} name password);
}
可以看到由於在調用時使用了命名參數參數的位置就不在重要了
可選參數
方法構造函數索引器和委托的定義可以指定其參數為必選的還是可選的在調用時必須提供必選參數但是可以省略可選參數
還可以使用SystemRuntimeInteropServicesOptionalAttribute特性類定義可選參數該類從時代就已經包含在基類庫中了
每一個可選參數的定義都包含默認值(默認值必須是常量)如果在調用時沒有指定該參數則使用默認值例如以下代碼
static void Main(string[] args)
{
CreateUser(adminadminpassword);
}
///
/// 創建用戶
///
///
用戶名稱
///
用戶密碼
///
積分
///
是否鎖定
static void CreateUser(string name
string password
int score=
bool isLocked=false)
{
Console
WriteLine(
name:{
}
password:{
}
name
password);
}
在所有必須參數後面定義可選參數如果在調用時提供了某個可選參數的值那麼必須提供該可選參數之前所有可選參數的值(如果此參數之前有可選參數)而不允許使用逗號分隔的形式提供參數即以下調用是錯誤的
CreateUser(adminadminpasswordtrue);
而必須寫成
CreateUser(adminadminpasswordtrue);
或者更好的解決辦法是使用命名參數
CreateUser(adminadminpasswordisLocked:true);
COM API訪問
命名和可選參數與dynamic和其他增強一起使得訪問COM API更加方便例如在C#或更早的版本中在調用某些COM API時如果要省略某些參數需要使用TypeMissing例如以下代碼(代碼系摘抄)
var excelApp = new MicrosoftOfficeInteropExcelApplication();
var myFormat =
MicrosoftOfficeInteropExcelXlRangeAutoFormatxlRangeAutoFormatAccounting;
excelAppget_Range(A B)AutoFormat(myFormat TypeMissing
TypeMissing TypeMissing TypeMissing TypeMissing TypeMissing);
但是有了命名和可選參數後可以很簡單的寫成這樣
excelAppget_Range(A B)AutoFormat( Format: myFormat );
類型等價支持(Type Equivalence Support)(此段為翻譯)
如果嵌入來自於強命名托管程序集的類型信息時可以使在某一應用程序中的類型與獨立的發布版本中類型保持松散的連接這意味著應用程序可以在不需要重新編譯每一個版本的情況下使用多個版本托管類庫中的類型
類型嵌入經常用於COM交互例如使用Microsoft Office中的自動化的應用程序嵌入類型信息允許同一個應用程序在安裝了不同的Office版本的機器上運行而且開發人員可以在完全托管解決方案中使用類型嵌入
來自於某個程序中可以嵌入的類型需要滿足以下條件
該程序集至少暴露一個公共接口
該嵌入接口使用ComImport和Guid特性聲明
該程序集使用ImportedFromTypeLib和一個程序集級別的Guid特性標注(默認情況下Visual Basic和Visual C#模版已包含了程序集的Guid特性)
在指定可以嵌入的公共接口後可以創建實現了這些接口的類客戶端程序可以在設計時引用包含了這些公共接口的程序何並且默認Embed Interop Types屬性為true以嵌入類型信息(在命令行使用/link編譯開關可以達到相同的效果)接下來客戶端可以創建這些接口的實例如果您創建了強命名運行時程序集的新版本
客戶端不需要使用新的程序集重新編譯相反客戶端程序通過公共接口的嵌入類型信息繼續使用可用的程序集的版本
首先創建一個強命名接口類庫(根據滿足條件設置屬性)
[ComImport]
[Guid(DAABFDF)]
public interface ISampleInterface
{
void GetUserInput();
string UserInput { get; }
}
創建強命名類庫引用接口類庫並定義實現以上接口的類
public classSampleClass: ISampleInterface
{
private stringp_UserInput;
public stringUserInput { get{ return p_UserInput; } }
public voidGetUserInput()
{
ConsoleWriteLine(Please enter a value:);
p_UserInput = ConsoleReadLine();
}
}
創建客戶端應用程序引用接口並使用反射的方法動態創建類型執行相應操作
class Program
{
static void Main(string[] args)
{
Assembly sampleAssembly = Assembly
Load(
TypeEquivalenceRuntime
);
ISampleInterface sampleClass =
(ISampleInterface)sampleAssembly
CreateInstance(
TypeEquivalenceRuntime
SampleClass
);
sampleClass
GetUserInput();
Console
WriteLine(sampleClass
UserInput);
Console
WriteLine(sampleAssembly
GetName()
Version
ToString());
Console
ReadLine();
}
}
修改實現了接口在的客戶端類
增加新的方法並修改程序集版本號和文件版本號為
public DateTime GetDate()
{
return DateTimeNow;
}
再次執行客戶端程序
觀察不同(客戶端將輸出新的版本號)
在NET全部使用托管代碼創建的程序集自動會識別更新也就是說不需要使用額外的屬性定義直接創建接口實現接口類庫和客戶端類(或者沒有接口直接創建類庫在客戶端引用)在類庫更新後復制到客戶端引用的位置客戶端會自動檢測到該更新這也是NET程序集為開發人員帶來的好處但是使用類型等價支持的作用體現在什麼地方我認為還是方便了COM API的訪問因為COM可能是使用其他語言編寫的沒有辦法做到像NET程序集那樣自動感應版本變化個人意見期望高手解答
總結
Visual C#中提供了動態類型命名參數可選參數和類型等價支持為編程帶來便利對於訪問COM API來說更方便了而且微軟多次提到了諸如Office之類的文字是不是意味著微軟在不斷的鼓勵程序員不斷開發出其於Office的一些應用亦或是現在其於Office的應用在不斷增加還是應用程序中與Office的交互在不斷增加通過增強的特性使這些工作更方便來鞏固微軟件地位?一家之言請高手不吝賜教
From:http://tw.wingwit.com/Article/program/net/201311/11278.html