我正在使用ESRI的ArcObjects COM库,我正在努力弄清楚"选择"应该是什么类型:
IMxDocument doc = m_application.Document as IMxDocument;
object selected = doc.SelectedItem;
Run Code Online (Sandbox Code Playgroud)
SelectedItem返回一个comobject(Not Null),通常表示当前选择的数据类型.但是我没有最微弱的想法,我应该把它投入到什么类型.当我调试它时,我真的没有看到任何有用的东西:
(在设置值后观察调试)
ESRI的ArcObjects库非常庞大,文档记录很差,我简直无法理解.我甚至竟然手动检查了大约50个我认为应该是的界面.
有没有人有任何想法我怎么能搞清楚这一点?
编辑澄清他们的文档绝对没有帮助,他们的论坛也没有.
我不熟悉那个图书馆,但我可以提出一些建议.一旦从COM的角度看问题,你就会发现没有简单的答案.
(请记住,在COM中所有对象都只是对象,并且唯一的要求是它必须支持IUNKNOWN(以及可能的其他接口).因此,问题"它是什么类型的对象"的答案通常可以有不止一个答案.)
需要记住的重要一点是,在COM中,对象的接口列表没有像在.NET中那样在任何类型的元数据中定义(除了库通常提供可选类型库作为开发工具的文档形式 - - 一分钟内更多内容).
接口列表仅由调用IUNKNOWN的QueryInterface()方法的结果正式定义 - 也就是说,它完全由执行代码的结果定义.
有时列表可能是硬编码的.通常情况下,列表可能直到运行时才会被人知道,甚至在有人要求之前就不会知道.唯一的规则是接口列表需要稳定,我称之为合理:列表不能随着时间的推移而改变给定的对象实例; 它必须支持IUNKNOWN,有时人们会忘记; 如果它支持派生接口,它必须支持它的基础; 和其他几个我相信我忘记了.
最后一点是你的问题的关键:COM不知道先验什么接口由任何对象支持..NET运行时也不知道 - 无论如何都不是来自COM..NET知道的唯一方法是,对象的类型库是否返回的对象是特定接口.缺少这一点,你只需要一个IUNKNOWN指针,你必须通过代码询问特定的接口,看看你是否得到了除NULL以外的答案.
由于SelectedItem属性的类型是对象,这意味着类型库只是简单地说"返回类型是IUNKNOWN类型的接口指针"(它可能是IDISPATCH,但原理是站立的).确切的类型显然取决于运行时的情况 - "现在恰好选择什么".
(在.NET中,返回类型实际上是System.__ComObject因为你没有得到一个裸接口指针,而是一个COM可调用包装器,它是基于.NET的代理对象)
你受库的(穷人?)文档的支配,以获得返回对象可能支持的接口类型的线索.缺乏这一点,像Chibacity这样的代码也可能会让你得到一个部分列表(我没有审查过那段代码).最终,您可能希望使用该代码在调试期间获取候选接口列表.
一旦你知道了一些你感兴趣的可能性,你可以通过使用C#as操作符(这会导致COM可调用包装器针对本机对象发出相应的COM法术)来节省一些打字麻烦.
在阅读了您的问题,答案和评论之后,您可能必须编写一个实用程序来通过暴力查找答案.
使用反射从interop程序集中删除接口列表,然后只需循环遍历此列表,并查看对象是否依次支持每个接口.
更新
一些示例代码:
object unknown = //your com object...
Type someComObjectType = typeof(ExampleTypeInInteropAssembly);
Assembly interopAssembly = someComObjectType.Assembly;
Func<Type, bool> implementsInterface = iface =>
{
try
{
Marshal.GetComInterfaceForObject(unknown, iface);
return true;
}
catch (InvalidCastException)
{
return false;
}
};
List<Type> supportedInterfaces = interopAssembly.
GetTypes().
Where(t => t.IsInterface).
Where(implementsInterface).
ToList();
if (supportedInterfaces.Count > 0)
{
supportedInterfaces.ForEach(Console.WriteLine);
}
else
{
Console.WriteLine("No supported interfaces found :(");
}
Run Code Online (Sandbox Code Playgroud)