2009-08-14 21 views
2

我有一個託管程序集包含幾個類,並且這些類具有重載的方法。我通過在COM互操作(CCW)中重載 - IDispatch名稱包含後綴(_2,_3等)

[ComVisible(true)] 

暴露大會COM/IDispatch接口調用方..和還設置適當的Guid,在大會本身。我沒有爲COM互操作定義明確的接口。這一切都是動態完成的。我在受管DLL上運行regasm.exe /codebase,並將其註冊爲COM互操作。

當我運行OLEVIEW,我能看到的各種類的ProgID的組件中。但是,瀏覽這些ProgIds並擴展IDispatch節點時,這些類沒有TypeLib信息。

即使如此,從腳本,我可以調用接受零個參數或接受一個參數的方法的方法。如果還有一個接受多個參數的重載,我不能通過名稱調用該方法。我得到的錯誤,始終如一,是

Microsoft VBScript runtime error: Wrong number of arguments or invalid property assignment: <methodname> 

從此我明白了COM/IDispatch的客戶不能夠妥善解決通過COM互操作暴露的對象上重載方法。


然後我說

[ClassInterface(ClassInterfaceType.AutoDual)] 

...每一個有問題的類。在DLL上的regasm.exe之後,我可以在IDispatch節點下看到每種方法的typelib信息。

我發現,重載方法會自動獲取包含附加後綴的名稱。 MethodX會將自動生成的typelib程序集中的重載公開爲MethodX,MethodX_2,MethodX_3等。

而且我發現,與那些後綴引用方法名,我可以調用重載方法,雖然不能與通用名稱。

更有趣的是,如果我然後從類除去[ClassInterface(ClassInterfaceType.AutoDual)],我可以仍然調用以這種方式重載方法,從而避免了錯誤Wrong number of arguments or invalid property assignment

我的問題是:是這樣的行爲 - 追加數字後綴成員名稱 - 穩定嗎?記錄?可信?

回答

5

COM不支持方法重載,所以.NET COM Interop層必須即興創作。我不確定名稱是否如您所描述的那樣隨處可見,但即使是這樣,我也不認爲使用它是一個好主意 - 對於COM用戶來說,它仍然是一個非常不方便的API。如果你想把你的類暴露給COM,最好的方法是編寫一個獨特的COM接口,並且隱藏這個類本身。以COM友好的方式處理重載的正確方法是使用一些參數(並將其委託給相應的.NET重載)。

1

以我的經驗,互操作生成MethodMethod_1,Method_2等是正常的和穩定的,但並不真正需要。令人討厭的是,重載不會跨越Managed/Unmanaged邊界。我試圖將COM-Visible方法重構爲具有唯一名稱的獨立方法,而不是爲其任意添加一個數字後綴,因此對於COM消費者而言更明顯的是所調用的方法。

1

是的,它的記錄在MSDN:

由於改變這將是一個記錄功能的「破變化」,我想你可以依靠它是「穩定」 。最大的缺點是您的方法名稱取決於它們在源文件中定義的訂單

但是請注意,COM支持可選的參數,因此使用它們可能是重載的可行替代方案。如果您需要添加重載爲二進制兼容到庫中的舊.NET客戶端,我發現下面的模式是有用的:

// used for binary-compatibility with .NET clients who currently use 
// the old, one-parameter version 
[ComVisible(false)] 
void myMethod(String oneParameter) { 
    ... 
} 

// since this is the first COM-visible version, it is assigned the "correct" name. 
void myMethod(String oneParameter, int newParameter = 0) { 
    ... 
} 

由於COM支持可選參數,既myMethod(string)myMethod(string, int)會工作。

+0

注意:使用VB.NET時,此技術(兩個重載只根據可選參數的不同)需要VS 2012。 – Heinzi 2012-11-21 14:46:41