概述C# COM接口相關知識
C# 4.0中有下面這些功能: 1. dynamic/IDynamicObject 這個改進使得C#向動態語言又進了一步,雖然C#并不會變成類似Perl/Python之類的動態語言(因為Anders認為靜態語言所支持的一些特性比如Intellisense,類型檢查等等是相當有用的),但是這并不代表C#不應該對動態特性提供更好的支持。從我們Interop的角度來看,dynamic比較類似COM中的IDispatch,也就是動態的根據提供的函數/屬性名字動態選擇匹配的動作并執行之,只不過這個接口現在變成了IDynamicObject。寫法也很類似VB6。原來要寫:
- object obj = GetObject();
- 2: obj.GetType().InvokeMember(“CallSomeFunc”, …., new object[] { 1 });
現在只需:
- dynamic obj = GetObject();
- obj.CallSomeFunc(1); // obj通過IDynamicObject接口,支持CallSomeFunc方法。
這一切都是通過IDynamicObject接口實現的。只要對象支持IDynamicObject,那么任意對象都可以通過這種方式來直接調用,不管是COM,Python,JavaScript,等等。這個功能感覺基本上就是定義一個C# COM接口,然后編譯器再把代碼翻譯一下就好了,關鍵還是各種對象的支持。 2. Optional Parameter / Named Parameters 以前C#特意不支持的可選參數終于現在可以支持了。命名參數也可以支持了,使用參數加冒號:
- OpenTextFile(“foo.txt”, Encoding.UTF8, bufferSize:123)
Improved COM Interoperability
1.Automatic object –> dynamic mapping 原來返回object的地方,現在object可以自動被視為dynamic。因此,以前需要cast的地方現在可以省去cast了,反正dynamic 對象可以通過IDynamicObject來間接調用IDispatch接口(我覺得應該還是通過MemberInfo.Invoke來間接調用 IDispatch,但是暫時沒有時間驗證其實現方式)來自動調用對應的函數,而不需要cast到對應的interface再調用。原來是: (Range)excel.Cells[1, 1].Value = xxx; 現在可以寫成:excel.Cells[1,1].Value = xxx; // call IDynamicObject.SetMember(“Value”, xxx);
2.Optional and named parameters 這個無需多說了吧。BTW,現在TlbImp的結果中(也就是Interop Assembly)已經在Metadata包含了缺省值,只是C#不用而已,現在C#可以直接使用了。
3.Indexed Property 這個Anders一句話帶過,暫時不清楚具體是什么改進。
4.Optional ref modifier 在COM Interop時候可以不用寫ref。具體的Anders也沒有多談。覺得應該是很小的改動。
5.Interop Type Embedding (NO PIA) 這個也就是之前我在前一篇提到的Type Equvalency。原來為了保證同一個C# COM接口具有相同的托管類型(因為對于同一個C# COM接口可以有多個對應的托管的接口),推薦使用PIA(Primary Interop Assembly)。但是,在使用PIA的過程中,發現PIA有不少問題,因此CLR Interop的某位牛人Architect想出了這個新Idea:不使用PIA,而是允許對應同一C# COM接口的不同托管接口之間可以互換使用,無需Cast,CLR內部將它們等價看待。這是一個比較大的改動,不管是對于編譯器,還是CLR。
【編輯推薦】