在这个相关问题中,我注意到 Visual Studio 的调试器能够枚举System.__ComObject
引用的属性,这是“当包装器类型不明确时使用的隐藏类型”——例如,当你从另一个获取它时获得的对象类型COM 对象,不要自己实例化它:
此外,如果您只是将 COM 对象的标识符写入即时窗口,它的属性和值也会被类似地转储:
请注意,这与 VS2010 的“动态视图”是分开的,我相信它使用IDispatch
和 COM 反射来枚举 COM 对象的属性,而不使用 PIA 和 .NET 反射。我正在使用的对象没有实现IDispatch
(它们也没有为此实现IProvideClassInfo
),因此,“动态视图”无法获取有关它们的任何信息:
有趣的是,SharpDevelop的调试器无法列出System.__Comobject
s 的成员(例如point.Envelope
),只能列出强类型的 RCW(例如point
)。
那么 Visual Studio 是如何做到的呢?
我相信在这种情况下,这是因为主互操作程序集存在这些对象支持的接口的定义,并且 Visual Studio 很可能使用反射来枚举支持的接口和属性。那准确吗?如果是这样,它是如何工作的?
首先,它如何访问 PIA?它只查看当前加载的 PIA 还是动态加载它们(如果是,如何加载)?它如何确定枚举属性的接口,其中可以有很多?它似乎只使用一个,不一定是第一个。从我正在使用的 API的文档IUnknown
(ArcObjects)来看,这些对象的默认接口是,因此它也不仅仅是使用默认接口。
在屏幕截图的示例中,它枚举成员的接口是IEnvelope
接口,它继承自IGeometry
接口。VS2010怎么知道不枚举成员IGeometry
,在我的测试中,如果你只枚举PIA中的所有接口类型,它首先出现?发生了一些非常聪明的事情,或者我错过了一些明显的事情?
我问的原因是,如果LINQPad 的开发人员知道 VS 是如何做到的,他似乎愿意实现相同的功能。因此,这里的一个好的答案可以大大有助于改进这个非常流行的工具。