我正在尝试使用LINQPad快速开发小型ArcObjects ( ESRI 的 ArcGIS软件的基于 COM 的库)应用程序,并且在将它用于我从 .NET 初始化的 COM 对象的属性方面取得了一些成功Dump()
,但任何 COM 对象从现有的 COM 对象中获取的对象被简单地转储为System.__ComObject
引用,这并不是特别有用:
这个帮助主题解释了为什么会发生这种情况,我想我理解,但想知道有哪些选项可以解决这种行为,特别是在使 LINQPad(甚至)更强大的情况下。
有趣的是,Visual Studio 的调试器能够显示这些对象的属性,甚至是值类型的值:
Visual Studio 使用什么机制来实现这种自省,为什么 LINQPad 的 Dump 方法不做同样的事情?编辑:请参阅有关 VS 如何执行此操作的相关问题:Visual Studio 的调试器/交互式窗口如何在 .NET 中转储 COM 对象的属性?
ArcObjects .NET SDK包括带有 RCW的PIA,每个 CoClass 可以实现 COM 接口,因此我认为应该可以以编程方式包装这些对象。
作为一种解决方法Marshal.CreateWrapperOfType()
,当我碰巧知道应该使用哪个 CoClass 时,我已在我的 LINQ 查询中成功使用强制 LINQPad 转储对象的属性。当然,这只会正确地转储值类型属性——任何基于 COM 的引用类型属性仍报告为System.__ComObject
,因此正确的解决方案必须递归地工作以将这些属性也包装起来。
在上一个问题中,我了解到 CoClass 可以在运行时确定,如果它实现IPersist
,ArcObjects 的很大一部分就是这样做的。我可以以某种方式使用这种技术或另一种技术来自动System.__ComObject
从 PIA 强制 a 到适当的 RCW 吗?如果是这样,我如何在 LINQPad 中实现它,例如通过提供ICustomMemberProvider
实现?是否可以将其设为递归,以便同时包装 COM 对象的属性?
我正在使用面向 .NET 4.0 的 LINQPad 4.x,但我也对支持 LINQPad 2.x 感兴趣(因此,首选适用于 .NET 3.5 和 .NET 4.0 的解决方案,但这不是必需的)。
更新:我已经弄清楚了问题的第一部分,即如何System.__ComObject
使用IPersist.GetClassID
. 有关我正在使用的代码,请参阅此相关问题和此答案。
我仍然想知道如何将其用于 LINQPad 的 Dump 方法。