title: How to get LINQPad to Dump() System.__ComObject references?
body: <p>I am playing around with using <a href="http://www.linqpad.net/" rel="nofollow noreferrer">LINQPad</a> to rapidly develop small <a href="http://en.wikipedia.org/wiki/ArcObjects" rel="nofollow noreferrer">ArcObjects</a> (a COM-based library for <a href="http://www.esri.com/software/arcgis" rel="nofollow noreferrer">ESRI's ArcGIS</a> software) applications and have had some success in using it to <code>Dump()</code> 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 <code>System.__ComObject</code> references, which is not particularly useful:</p>
  
  <p><img src="https://i.stack.imgur.com/i4lYZ.png" alt="LINQPad Screenshot"></p>
  
  <p><a href="http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//000100000151000000" rel="nofollow noreferrer">This help topic</a> 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.</p>
  
  <p>Interestingly, Visual Studio's debugger is able to display the properties of these objects, and even values for value types:</p>
  
  <p><img src="https://i.stack.imgur.com/G0Bug.png" alt="Visual Studio debugging ArcObjects"></p>
  
  <p>What mechanism does Visual Studio use to achieve this introspection, and why doesn't LINQPad's Dump method do the same? <strong>Edit:</strong> See related question about how VS does this: <a href="https://stackoverflow.com/q/14798159/386205">How does Visual Studio&#39;s debugger/interactive window dump the properties of COM Objects in .NET?</a></p>
  
  <p>The <a href="http://help.arcgis.com/en/sdk/10.0/arcobjects_net/ao_home.html" rel="nofollow noreferrer">ArcObjects .NET SDK</a> 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.</p>
  
  <p>As a workaround I have successfully used <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.createwrapperoftype.aspx" rel="nofollow noreferrer"><code>Marshal.CreateWrapperOfType()</code></a> 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 <code>System.__ComObject</code>, so a proper solution would have to work recursively to get those wrapped as well.</p>
  
  <p>In a <a href="https://stackoverflow.com/q/3348554/386205">previous question</a> I learned that the CoClass can be determined at runtime if it implements <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms688695%28v=vs.85%29.aspx" rel="nofollow noreferrer"><code>IPersist</code></a>, which a good portion of ArcObjects do. Can I somehow use this technique, or another one, to automatically coerce a <code>System.__ComObject</code> to the appropriate RCW from the PIAs? And if so, how can I implement this in LINQPad, e.g. by providing an <a href="http://www.linqpad.net/faq.aspx#extensibility" rel="nofollow noreferrer"><code>ICustomMemberProvider</code></a> implementation? Can this be made to be recursive, so that properties that are also COM objects be wrapped as well?</p>
  
  <p>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).</p>
  
  <p><strong>Update:</strong> I've figured out the first part of my question which was how to wrap a <code>System.__ComObject</code> in its RCW using the CLSID returned by <code>IPersist.GetClassID</code>. See this <a href="https://stackoverflow.com/q/14756823/386205">related question</a> and <a href="https://stackoverflow.com/a/14765248/386205">this answer</a> for the code I'm using.</p>
  
  <p>I would still like to know how I can work this into LINQPad's Dump method.</p>