C#动态和动态;COM对象

C#动态和动态;COM对象,c#,.net,dynamic,.net-4.0,C#,.net,Dynamic,.net 4.0,当你开始思考时,动态类型的一个非常大的优势就出现了 关于C#与外部和非本机对象的关系–COM 特别是物体。在这种情况下,使用 COM IDispatch接口,这反过来意味着您可以使用 COM对象“原始”,即没有主互操作程序集(PIA)。作为 许多COM对象广泛使用变量类型,它可以 存储多种标准数据类型中的任意一种,能够使用 替代变体的动态类型是一个很大的简化 我已经知道动态是如何在C#中使用的,但是-我想知道它是如何完成的。(通常使用COM) 查看Office COM对象模型示例: (Excel

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

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

查看Office COM对象模型示例:

(Excel.Range)excel.Cells[1,1]).Value= "some string"
必须包括强制转换,因为
PIA
使用对象类型来表示变体

现在(2010年…),使用dynamic可通过以下方式完成:

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]或[added code]或[now inherit DynamicObject]
COM对象是否允许
excel.Cells[1,1].Value=“some string”
工作


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

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

以下行可以工作,不需要DateTime从DynamicObject继承:

dynamic myDate=DateTime.Now;
编辑

至于COM+如何支持动态绑定,它一直都支持。事实上,文档准确地解释了如何做到这一点

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

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


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

不,秘方在这里。这只需要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库。

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

这与……中的com有关。。。。。。。。?(我知道动态将执行留给运行时)我的意思是(就像你说的)MS希望他们的类也提供一个动态接口。因此,我的问题是他们是否更改了任何内容以允许查看编辑,而不是
(Excel.Range)Excel.Cells[1,1]).Value=“some string”
--->
Excel.Cells[1,1].Value=“some string”
。他们不需要更改任何内容,COM始终支持通过Idispatch进行动态绑定,这是因为在动态之前使用了Idispatch?非常感谢Hans。在COM时代,我错过了一些方面……功能强大的“QueryInterface”就是其中之一……这将添加回.NET 5: