如何获得LINQPad转储()系统.__ ComObject参考? [英] How to get LINQPad to Dump() System.__ComObject references?

查看:197
本文介绍了如何获得LINQPad转储()系统.__ ComObject参考?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用 LINQPad 快速开发小型的的ArcObjects (为的 ESRI的ArcGIS软件)应用程序,并有过用它来转储()的COM对象,我从.NET初始化属性,但任何这是从现有的COM对象获得的COM对象简单地倾倒为系统.__ ComObject 引用,这是不是特别有用:

I am playing around with using LINQPad to rapidly develop small ArcObjects (a COM-based library for ESRI's ArcGIS software) applications and have had some success in using it to Dump() the properties of COM objects that I initialize from .NET, but any COM objects that are obtained from an existing COM object are simply dumped as System.__ComObject references, which is not particularly useful:

此帮助主题解释为什么发生这种情况,这是我想我明白,但想知道哪些选项有用于解决此问题的工作,尤其在使LINQPad(偶数)更强大的情况下。

This help topic explains why this is happening, which I think I understand, but would like to know what options there are for working around this behavior, especially in the context of making LINQPad (even) more powerful.

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

Interestingly, Visual Studio's debugger is able to display the properties of these objects, and even values for value types:

什么机制并Visual Studio中使用,以实现这一反省,为什么不LINQPad的转储方法做相同? 修改查看关于VS怎么做相关的问题是:如何Visual Studio中的调试器/交互式窗口倾倒的属性在.NET?

What mechanism does Visual Studio use to achieve this introspection, and why doesn't LINQPad's Dump method do the same? See related question about how VS does this: How does Visual Studio's debugger/interactive window dump the properties of COM Objects in .NET?

ArcObjects的.NET SDK 包括为每个伴生类COM接口可以被实现的RCW PIA的,所以我想应该可以以编程方式包装这些对象。

The ArcObjects .NET SDK includes PIAs with RCWs for each CoClass a COM interface may be implemented by, so I'm thinking it should be possible to wrap these objects programmatically.

作为一种变通方法我已经成功地使用的 Marshal.CreateWrapperOfType() 我的LINQ查询中强迫LINQPad转储对象的属性时,我碰巧知道伴生类应该被使用。当然,这只是正常转储​​值类型属性 - 任何基于COM的引用类型属性仍然报告为系统.__ ComObject ,因此妥善解决将不得不递归工作让这些包装也是如此。

As a workaround I have successfully used Marshal.CreateWrapperOfType() within my LINQ queries to coerce LINQPad to dump the properties of the object when I happen to know which CoClass should be used. Of course, this only properly dumps value type properties -- any COM-based reference type properties are still reported as System.__ComObject, so a proper solution would have to work recursively to get those wrapped as well.

在一个前面的问题我据悉,组件类可以在运行时确定的,如果它实现的 的IPersist ,它的ArcObjects的很大一部分做的。我能以某种方式使用这种技术,或者另外一个,自动强制一个系统.__ ComObject 从PIA的适当RCW?如果是这样,我怎么能在LINQPad实现这一点,例如通过提供 ICustomMemberProvider 执行?可以这样做是递归的,所以这也是COM对象的属性被包呢?

In a previous question I learned that the CoClass can be determined at runtime if it implements IPersist, which a good portion of ArcObjects do. Can I somehow use this technique, or another one, to automatically coerce a System.__ComObject to the appropriate RCW from the PIAs? And if so, how can I implement this in LINQPad, e.g. by providing an ICustomMemberProvider implementation? Can this be made to be recursive, so that properties that are also COM objects be wrapped as well?

我使用LINQPad 4.x的哪些目标.NET 4.0,但我也有兴趣支持LINQPad 2.x的(这样两个.NET 3.5和.NET 4.0用的解决方案将是首选,但是这不是必须的)。

I am using LINQPad 4.x which targets .NET 4.0, but am also interested in supporting LINQPad 2.x (so solutions that work on both .NET 3.5 and .NET 4.0 would be preferred, but that's not a requirement).

< STRONG>更新:我已经想通了,我的问题的第一部分,这是如何包装一个系统.__ ComObject 在RCW code> IPersist.GetClassID 。看到这个相关问题这回答因为我正在使用的代码。

Update: I've figured out the first part of my question which was how to wrap a System.__ComObject in its RCW using the CLSID returned by IPersist.GetClassID. See this related question and this answer for the code I'm using.

我还是想知道我可以工作到LINQPad的dump方法这一点。

I would still like to know how I can work this into LINQPad's Dump method.

推荐答案

我一直有一些相同的问题(除了我与iTunes COM库的工作)。

I've been having some of the same issues (except I'm working with iTunes COM library).

在Visual Studio中,你没有意识到这一点,但每一个调试窗口,询问COM库当你打开它来创建类型。这比转储(),这是,嗯,没有互动的不同。

In visual studio you don't realize it but each debug window is asking the COM library to create the type when you open it. This is different than Dump() which is, well, not interactive.

我发现的唯一的解决办法是,如果我知道什么类型的列表是做一个 OfType<>()转换到该类型。这将遍历列表,并迫使COM创建元素

The only solution I've found is if I know what type the list is to do a OfType<>() cast to that type. This will iterate over the list and force COM to create the elements.

因此​​,在你上面的例子,你会说:

So in your example above you would say:

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



NB - 你millage可能会有所不同,事实证明这是必要的OP例子

NB - Your millage may vary, it turns out for the OP example this was needed.

var layers = map.EnumerateLayers()
      .OfType<IGeoFeatureLayer>()
      .Dump();



根据COM你可能借此下一步骤,并从那里拉出成员(与COM你要问得到的值)是这样的:

Depending on the COM you might have to take this to the next step and pull out the members from there (with com you have to ask to get the value) something like this:

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



肯定将是很好,如果有一个神奇的方式来做到这一点,但我不'难以相信,还有是因为COM的本质。

Sure would be nice if there was a "magical" way to make this happen, but I don't believe there is because of the nature of COM.

这篇关于如何获得LINQPad转储()系统.__ ComObject参考?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆