これが、概念実証としてまとめたものです。実際には、ほんの一握りの拡張メソッドです。IPersist
これは、現在にロードされているPIAの1つにRCWクラスを実装して持つCOMオブジェクトに依存していますAppDomain
。
internal static class ExtensionMethods
{
internal static object ConvertToRCW(this object o)
{
var guid = o.GetCLSID();
if (guid != Guid.Empty)
{
return Marshal.CreateWrapperOfType(o, o.GetTypeFromGuid(guid));
}
else
{
return o;
}
}
internal static Guid GetCLSID(this object o)
{
Guid guid = Guid.Empty;
var p = o as IPersist;
if (p != null)
p.GetClassID(out guid);
return guid;
}
internal static Type GetTypeFromGuid(this object o, Guid guid)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var assembly in assemblies)
{
var types = assembly.GetLoadableTypes();
foreach (var type in types)
{
if (type.GUID == guid)
return type;
}
}
return o.GetType();
}
internal static IEnumerable<Type> GetLoadableTypes(this Assembly assembly)
{
try
{
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
return e.Types.Where(t => t != null);
}
}
}
このように使用されます:
var point = new ESRI.ArcGIS.Geometry.Point();
point.PutCoords(1, 1);
Console.WriteLine(point.GetType().FullName);
Console.WriteLine(point.Envelope.GetType().FullName);
Console.WriteLine(point.Envelope.ConvertToRCW().GetType().FullName);
次の出力が得られます。
ESRI.ArcGIS.Geometry.PointClass
System .__ ComObject
ESRI.ArcGIS.Geometry.EnvelopeClass
これは望ましい結果でした。ここで、これをLINQPad(私の元の質問)でうまく機能させるために。