C#动态和COM对象

Roy*_*mir 2 .net c# dynamic .net-4.0

从这里

当您开始考虑C#与外部和非本机对象的关系时,动态类型的一个非常大的优势就来了 - 特别是COM对象.在这种情况下,使用COM IDispatch接口解析动态类型,这反过来意味着您可以使用"原始"COM对象,即没有主互操作程序集(PIA).由于许多COM对象广泛使用变量类型,它可以存储许多标准数据类型中的任何一种,因此能够使用动态类型代替变体是一个很大的简化.

我已经知道C#中是如何使用动态的,但是 - 我想知道它是如何完成的.(通常使用COM)

查看Office COM对象模型示例:

(Excel.Range)excel.Cells[1,1]).Value= "some string"
Run Code Online (Sandbox Code Playgroud)

演员必须包括由于PIA使用对象类型来表示变种

现在(2010 ...),动态可以通过以下方式完成:

excel.Cells[1,1].Value= "some string"
Run Code Online (Sandbox Code Playgroud)

对象可以通过实现提供其绑定语义 DynamicObject

如 :

public class MyClass: DynamicObject
{
  public override bool TryInvokeMember (  InvokeMemberBinder binder, object[] args, out object result)
    {
      ...
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题:

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

他们重建了这整个机制吗?

Han*_*ant 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()使用dispid调用属性getter/setter的COM方法

这是大局,如果您想了解更多有关这些接口的信息,请使用MSDN Library.