【发布时间】:2013-01-25 17:30:19
【问题描述】:
在这个related question 中,我注意到Visual Studio 的调试器能够枚举System.__ComObject 引用的属性,这是“当包装类型不明确时使用的隐藏类型”——例如,你的对象类型get 当你从另一个 COM 对象获取它并且不自己实例化它时:
此外,如果您只是将 COM 对象的标识符写入即时窗口,它的属性和值也会被类似地转储:
请注意,这与 VS2010 的“Dynamic View”是分开的,我相信它使用IDispatch 和 COM 反射来枚举 COM 对象的属性,而不使用 PIA 和 .NET 反射。我正在使用的对象不实现IDispatch(他们也没有实现IProvideClassInfo),因此,“动态视图”无法获取有关它们的任何信息:
有趣的是,SharpDevelop 的调试器无法列出System.__Comobjects 的成员(例如point.Envelope),只能列出强类型的RCW(例如point)。
那么 Visual Studio 是如何做到的呢?
我相信在这种情况下,这是因为主互操作程序集存在这些对象支持的接口的定义,并且 Visual Studio 很可能使用反射来枚举支持的接口和属性。那准确吗?如果是这样,它是如何工作的?
首先,它如何访问 PIA?它只查看当前加载的 PIA 还是动态加载它们(如果是,如何加载)?它如何确定枚举属性的接口,其中可以有很多?它似乎只使用一个,不一定是第一个。从我正在使用的 API (ArcObjects) 的documentation 来看,这些对象的默认接口是IUnknown,因此它也不仅仅是使用默认接口。
在截图的例子中,它枚举成员的接口是IEnvelope接口,它继承自IGeometry接口。 VS2010怎么知道不枚举IGeometry的成员,在我的测试中,如果你只枚举PIA中的所有接口类型,它首先出现?发生了一些非常聪明的事情,或者我可能遗漏了一些明显的事情?
我问的原因是LINQPadappears willing 的开发人员如果知道 VS 是如何做到的,就可以实现相同的功能。因此,这里的一个好的答案可以大大有助于改进这个非常流行的工具。
【问题讨论】:
-
由于Point类的Envelope属性的类型在PIA中定义为IEnvelope,VS可以dump,不需要特殊机制。
-
嗯,真的那么简单吗?此信息是否仅在调试时可用? (如何)在运行时可以获得相同的信息?以及为什么 SharpDevelop 的调试器不做同样的事情(也许他们只是不关心)。
-
是的,非常简单。当您只有 System._ComObject 时会更复杂,但是当您可以将它们转换为 ComImport .NET 接口时,您就可以访问这些接口布局。它随时可用,包括智能感知。我不了解 SharpDevelop。
标签: visual-studio-2010 com com-interop linqpad arcobjects