3

从这里

当您开始考虑 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"工作?

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

4

3 回答 3

6

不,秘诀就是这里的 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 库。

于 2012-12-31T08:24:06.783 回答
2

DLR(这是动态关键字提供的接口)使用“绑定器”与适当的动态对象进行交互(有 C# 绑定器、VB 绑定器、COM 绑定器等)。COM 绑定器是一个单独的组件,它使用“传统”COM 互操作,它没有被替换,仍然可以在没有动态的情况下使用。它针对 .NET 4.0 进行了增强,但不仅仅针对动态。

于 2012-12-31T08:25:19.113 回答
1

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

以下行有效,无需 DateTime 从 DynamicObject 继承:

dynamic myDate=DateTime.Now;

编辑

至于 COM+ 如何支持动态绑定——它一直都支持。事实上,文档准确地解释了这是如何完成的。

COM 始终通过 IDispatch 接口支持其自己的动态绑定,其工作方式与 DynamicObject 大致相似。IDispatch 允许对象响应对特定接口及其支持的方法的查询。

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

COM 中的动态绑定引入了性能损失,因为提取特定接口并调用其方法需要多次调用。在 VB6 时代,人们试图通过使用类型库来最小化或消除动态绑定的使用。这也是对 .NET 的合理建议。

于 2012-12-31T07:50:34.623 回答