Mads Torgersen給大家展示了C#中dynamic關鍵字的更多詳細信息以及它的一些具體用法並談及在選用dynamic關鍵字之前一些最終被廢棄的替代設計方案
C# 將通過新的元類型dynamic來添加對後期綁定的支持任何直接聲明為這種類型的變量或者從函數中返回這種類型的值都將自動地視為後期綁定這類似於在Visual Basic中把變量聲明為object不過它現在可以支持任何類型系統了不僅僅是CTS(通用類型規范)和COM
一個重要之處是這個特性的目標就是為了支持後期綁定以及更多地為了支持近來流行的動態綁定動態類型明顯不是C#的一個特性【譯者注意指C#是靜態語言本來無需動態類型的】不過是為了支持動態綁定的一個後果
還要著重注意的一點是反射並不是一種很好的替代方案使用反射的問題在於需要處理各種各樣的類型使用Reflection命名空間調用方法的方式和在ScriptObject上調用方法的方式並不相同尤其Ruby/Python方法這樣的第三方方法
一種選擇是用波形號作為動態操作的前綴可惜這種方式馬上也變得難以使用尤其在你開始研究類型轉換數組索引和數學操作符的地方
object d = GetDynamicObject(); string result = ~(string) d ~[ d~
Length ~
];
下一個曾考慮過的選擇是動態上下文類似unsafe和unchecked上下文那樣你能夠標注任意的代碼塊為dynamic這種方式的問題在於它很難把靜態和動態代碼混合在一起這種方式書寫的代碼類似下面
dynamic {
//some dynamic code
static {
//some statically bound code
dynamic {
//some dynamic code in some static code
}
//some more statically bound code
}
//some more dynamic code
}
第三種方案是傳播性的表達式由於表達式的動態本質將產生向上傳播的問題
object d = GetDynamicObject();
string result = (string) d[ dynamic(d)
Length
];
當然它們選擇的語法也不夠完美雖然可以讓大家輕易地讀懂代碼但是沒有任何東西來表明一個動態調用是在實際Call Site當中被創建出來的唯一看到的信息是這個變量在哪裡聲明的
dynamic d = GetDynamicObject();
string result = (string) d[d
Length
];
選用這種設計的關鍵原因是代碼未必真的不夠安全進行動態調用本身就像之前拋出異常那樣不過現在你不用編寫所有臃腫易出錯的反射邏輯了
另外一個曾考慮過的選擇是用dynamic修飾符來代替元類型使用這種模式的代碼如下所示開發人員能夠早期綁定到Foo的方法上而不是在任何東西上進行後期綁定雖然這樣可以在一些邊界情況下提高性能不過它卻增加了總體的復雜等級這樣的復雜度是難以接受的
dynamic Foo d = GetDynamicFooObject();
每逢動態組件進入到表達式中整個表達式將可能成為動態的這包括
方法調用
程序調用
成員訪問
操作符運用
索引訪問
例外是相當顯而易見的轉換和構造器將返回給你靜態上下文雖然轉換能被DLR類型系統所重寫但是DLR會把轉換的結果指定為適當的類型
From:http://tw.wingwit.com/Article/program/net/201311/15534.html