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