【问题标题】:C# dynamic & COM objectsC# 动态和 COM 对象
【发布时间】:2012-12-15 10:58:14
【问题描述】:

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" 工作?

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

【问题讨论】:

    标签: c# .net dynamic .net-4.0


    【解决方案1】:

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

    【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      您可以将dynamic 用于任何类型。仅当您希望 您的 类提供动态接口时,您才需要从 DynamicObject 派生。

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

      dynamic myDate=DateTime.Now;
      

      编辑

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

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

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

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

      【讨论】:

      • 这与com in........有关吗? (我知道动态将执行留给运行时)
      • 我的意思是(就像你说的)MS 希望 他们的 类也能提供动态接口。所以不是(Excel.Range)excel.Cells[1,1]).Value= "some string" ---->excel.Cells[1,1].Value= "some string" 我的问题是他们是否改变了任何东西以允许这样做
      • 查看编辑。他们不需要更改任何东西,COM 始终支持通过 IDispatch 进行动态绑定
      • 那么这个 Idispatch before dynamic 的用途是什么?
      猜你喜欢
      • 2011-06-29
      • 2013-10-04
      • 2011-07-05
      • 1970-01-01
      • 2014-09-01
      • 1970-01-01
      • 2011-01-20
      • 2014-12-27
      • 2013-02-02
      相关资源
      最近更新 更多