如何让LINQPad转到Dump()系统.__ ComObject引用?

我正在使用LINQPad来快速开发小型ArcObjects (一个基于COM的ESRI ArcGIS软件库)应用程序,并且已经成功地将它用于Dump()我从.NET初始化的COM对象的属性,但是从现有COM对象获取的COM对象只是作为System.__ComObject引用转储,这不是特别有用:

LINQPad截图

这个帮助主题解释了为什么会发生这种情况,我认为我理解,但是想知道解决这种行为有哪些选择,特别是在使LINQPad(甚至)更强大的环境中。

有趣的是,Visual Studio的调试器能够显示这些对象的属性,甚至是值类型的值:

Visual Studio调试ArcObjects

Visual Studio使用什么机制来实现这种内省,为什么LINQPad的Dump方法不会这样做呢? 编辑:请参阅有关VS如何执行此操作的相关问题: Visual Studio的调试器/交互式窗口如何在.NET中转储COM对象的属性?

ArcObjects .NET SDK包含带有RCW的PIA,每个CoClass可以通过COM接口实现,所以我认为应该可以以编程方式包装这些对象。

作为一种解决方法,我在LINQ查询中成功使用Marshal.CreateWrapperOfType()来强制LINQPad在我碰巧知道应该使用哪个CoClass时转储对象的属性。 当然,这只能正确转储值类型属性 – 任何基于COM的引用类型属性仍然报告为System.__ComObject ,因此正确的解决方案必须以递归方式工作以获取那些包装。

在之前的一个问题中,我了解到CoClass可以在运行时确定它是否实现了IPersist ,这是ArcObjects的很大一部分。 我可以以某种方式使用这种技术或其他技术自动将System.__ComObject从PIA System.__ComObject为适当的RCW吗? 如果是这样,我如何在LINQPad中实现它,例如通过提供ICustomMemberProvider实现? 这可以是递归的,这样也可以包装也是COM对象的属性吗?

我正在使用面向.NET 4.0的LINQPad 4.x,但我也对支持LINQPad 2.x感兴趣(因此,首选适用于.NET 3.5和.NET 4.0的解决方案,但这不是必需的)。

更新:我已经弄清楚我的问题的第一部分是如何使用IPersist.GetClassID返回的CLSID在其RCW中包装System.__ComObject 。 请参阅此相关问题和我正在使用的代码的答案 。

我仍然想知道如何将其用于LINQPad的Dump方法。

我一直有一些相同的问题(除了我正在使用iTunes COM库)。

在visual studio中你没有意识到它,但是每个调试窗口都要求COM库在你打开它时创建类型。 这与Dump()不同,Dump()不是交互式的。

我发现的唯一解决方案是,如果我知道该列表是什么类型的OfType<>()强制转换为该类型。 这将迭代列表并强制COM创建元素。

所以在上面的例子中你会说:

 var layers = map.EnumerateLayers("etc") .Select(s => s.OfType()) .Dump(); 

注意 – 你的millage可能会有所不同,事实certificate这是需要的OP示例。

 var layers = map.EnumerateLayers() .OfType() .Dump(); 

根据COM的不同,您可能需要将其转到下一步并从那里拉出成员(使用com,您必须要求获取值),如下所示:

 var layers = map.EnumerateLayers("etc") .Select(x => x.OfType()) .Select(x => new { x.Depth, x.Dimention, }) // etc .Dump(); 

如果有一种“神奇”的方法可以实现这一点,那肯定会很好,但我不相信因为COM的性质而存在。