c#动态&COM对象
本文关键字:对象 COM 动态 | 更新日期: 2023-09-27 17:50:17
from here
当你开始思考时,动态类型的一个非常大的优势就出现了关于c#与外部和非本机对象——COM的关系特别是对象。在这种情况下,使用COM IDispatch接口,这反过来意味着您可以使用COM对象"原始",即没有主互操作程序集(PIA)。作为许多COM对象广泛地使用了变体类型,这可以存储多种标准数据类型中的任意一种,可以使用动态类型代替变量是一个很大的简化。
我已经知道动态在c#中是如何使用的,但是-我想知道它是如何完成的。(一般使用COM)
查看Office COM对象模型示例:
(Excel.Range)excel.Cells[1,1]).Value= "some string"
必须包含强制转换,因为PIA
使用对象类型来表示变量
现在(2010…),有了动态,可以这样做:
excel.Cells[1,1].Value= "some string"
对象可以通过实现DynamicObject
例如:
public class MyClass: DynamicObject
{
public override bool TryInvokeMember ( InvokeMemberBinder binder, object[] args, out object result)
{
...
}
}
我的问题是:
是否MS [changed] or [added code] or [now-inherit-DynamicObject]
的COM对象,以允许excel.Cells[1,1].Value= "some string"
工作?
他们重建了整个机制吗?
不,这里的秘诀是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库
DLR (dynamic关键字提供接口的对象)使用"binder "来与动态对象进行适当的接口(有c# binder, VB binder, COM binder等)。COM绑定器是一个独立的组件,它使用"传统的"COM互操作,它不能被替换,并且在没有动态的情况下仍然可以使用。它在。net 4.0中得到了增强,但不仅仅是针对动态。
您可以将dynamic
用于任何类型。只有当您希望您的类提供动态接口时,才需要从DynamicObject
派生。
下面一行可以工作,不需要从DynamicObject继承DateTime:
dynamic myDate=DateTime.Now;
编辑
至于COM+如何支持动态绑定——它一直都支持。事实上,文档详细解释了这是如何完成的。
COM总是通过IDispatch接口支持自己的动态绑定,它的工作原理与DynamicObject大致相似。IDispatch允许对象响应针对特定接口及其支持的方法的查询。 dynamic
可以为原始COM对象使用IDispatch接口,在没有类型库或代理的情况下。在其他情况下,dynamic
将不通过IDispatch接口调用代理方法。
COM中的动态绑定会导致性能下降,因为需要多次调用来提取特定的接口并调用其方法。在VB6时代,人们试图通过使用类型库来最小化或消除动态绑定的使用。这也是对。net的合理建议。