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:
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.
Interestingly, Visual Studio's debugger is able to display the properties of these objects, and even values for value types:
What mechanism does Visual Studio use to achieve this introspection, and why doesn't LINQPad's Dump method do the same? Edit: See related question about how VS does this: How does Visual Studio's debugger/interactive window dump the properties of COM Objects in .NET?
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.
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.
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?
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).
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.
I would still like to know how I can work this into LINQPad's Dump method.
IDispatch
. Since none of the objects I'm working with implementIDispatch
it has to be the former, at least for the normal part of the debug view. I believe in VS2010's "Dynamic" view it usesIDispatch
. With my objects, though, Dynamic view only says "No further information on this object could be discovered". – MontanezIPersist
, which is definitely not universal. Could you suggest whether providing anICustomMemberProvider
for my RCW conversion approach is feasible? – MontanezICustomMemberProvider
in a way that it works on allSystem.__ComObject
s? Or is it only possible to to use on user-defined types? – Montanez