2012-12-31 106 views
1

from hereC#动态和COM对象

当你开始觉得 约C#的外部和非本地对象的关系动态类型的一个非常大的优势来 - COM特别 对象。在这种情况下,使用COM IDispatch接口使用 来解析动态类型,这又意味着您可以使用 COM对象为“原始”,即不使用主互操作程序集(PIA)。由于 许多COM对象都广泛使用变体类型,它可以存储任意数量的标准数据类型,能够使用动态类型代替变体是一种很大的简化。

我已经知道如何动态在C#中使用,但是 - 我想知道它是怎么做的(通常与COM)

看着办公室COM对象模型例如:

(Excel.Range)excel.Cells[1,1]).Value= "some string" 

的投必须包括因为PIA使用对象类型来表示变体

现在(2010 ...),动态这是可以做到的:

excel.Cells[1,1].Value= "some string" 

一个对象可以提供其通过实施结合语义DynamicObject

如:我的问题:

确定MS [changed] or [added code] or [now-inherit-DynamicObject] COM对象以允许excel.Cells[1,1].Value= "some string"工作?

他们是否重新构建了整个机制?

回答

5

不,这里的秘诀就是COM。这只用2个接口和5个方法完成。第一个是IUnknown,一个由所有COM对象实现的接口。它有3种方法:

  • AddRef(),增加COM对象的引用计数。这是一个内存管理功能,只要计数不为零,对象就保持活动状态。存储指向COM对象的指针需要调用IUnknown.AddRef()。

  • Release(),递减引用计数。与AddRef相反,必须在不再使用接口指针时调用。当计数达到零时,COM对象被释放。此函数是使用Office的.NET代码中Marshal.ReleaseComObject()的臭名昭着的使用背后的核心原因。它通常被COM包装器的终结器调用。

  • QueryInterface(),要求COM对象返回一个指向另一个接口的指针。在这个问题的范围内,这就是C#如何获取IDispatch接口指针。

IDispatch接口是实现动态绑定的接口,大致相当于DynamicObject。它有4个方法,其中2在这方面是重要的:

  • GetIDsOfNames将(),名称转换为数字,DISPID。这就是C#程序中的标识符如何与COM对象上的方法或属性名称匹配的方式。

  • 的invoke()调用属性的getter/setter方法的COM方法,使用DISPID

这是一个大的图片,如果你想知道更多关于这些接口使用MSDN库。

+0

非常感谢Hans。 –

+0

我从COM日中错过了一些*方面......全能的“QueryInterface”就是其中之一...... – JerKimball

1

您可以使用任何类型的dynamic。只有当您想要类提供动态接口时,才需要从DynamicObject派生。

下面这行工作,而无需日期时间从DynamicObject继承:

dynamic myDate=DateTime.Now; 

编辑

至于COM +如何支持动态绑定 - 它总是这样。实际上,文档解释了如何完成这项工作。

COM总是通过IDispatch接口支持它自己的一种动态绑定,它大致像DynamicObject一样工作。 IDispatch允许对象响应特定接口及其支持的方法的查询。

dynamic可以使用原始COM对象的IDispatch接口,其中没有类型库或代理。在其他情况下,dynamic将在不通过IDispatch接口的情况下调用代理方法。

由于需要多次调用一个特定的接口并调用它的方法,因此COM中的动态绑定引入了一个性能问题。在VB6时代,人们试图通过使用类型库来最小化或消除使用动态绑定。这也是对.NET的忠告。

+0

这与COM中的........有关吗? (我知道动态将执行留给运行时) –

+0

我的意思是(就像你说的)MS想要_their_类也提供一个动态的接口。所以而不是'(Excel.Range)excel.Cells [1,1])。Value =“some string”'> excel.Cells [1,1] .Value =“some string”'我的问题他们是否改变了_anything_以便允许那个 –

+0

查看编辑。他们不需要改变任何东西,COM始终支持通过IDispatch的动态绑定 –

2

DLR(这是动态关键字提供的接口)使用“活页夹”来与动态对象本身进行交互(有一个C#活页夹,VB活页夹,COM活页夹等)。 COM活页夹是一个独立的组件,它使用“传统的”COM互操作,它不被替换,并且仍然可以在没有动态的情况下使用。它已针对.NET 4.0进行了增强,但不仅适用于动态。