Mic*_*ous 4 c# com casting dynamic type-conversion
是否可以将System .__ ComObject强制转换为某种类型,仅在运行时才知道?我有以下代码
Type ComClassType = SomeDLLAssembly.GetType("ClassName");
dynamic comClassInstance = icf2.CreateInstanceLic(null, null, ComClassType.GUID, "License string");
//This will throw exception, because comClassInstance type is __ComObject and it does not contains ComClassMethod
comClassInstance.ComClassMethod();
Run Code Online (Sandbox Code Playgroud)
当我将使用下面的代码时,它工作正常,但不幸的是我不能在我的代码中使用InvokeMember,因为它会非常复杂.
ComClassType.InvokeMember("ComClassMethod", BindingFlags.InvokeMethod, null, comClassInstance, null);
Run Code Online (Sandbox Code Playgroud)
所以我想问一下,是否可以将"comClassInstance"转换为"ComClassType",以便能够以这种方式调用方法comClassInstance.ComClassMethod();
哪个只在运行时才知道?
至少部分问题.在编译时知道类型时,只能使用强制转换.你不知道所以你不能写出演员表达.但它比那更深,你不知道运行时的类型. __ComObject是RCW的低级包装器,它存储IDispatch接口指针.它没有说明您可以调用哪些方法以及可以使用哪些属性.
这是一个较低的打字级别,它是动态打字.一般术语是后期绑定.这是另一种程序员编写的与代码接口的尝试 - 调用 - 看到 - 发生的方式.C#团队长时间抵制它,静态类型是语言的核心,迫使程序员使用Reflection.但是,根据受欢迎的需求,他们在v4中添加了动态关键字,使得C#与Visual Basic保持一致,并始终支持它.您现在可以使用符号而不是将字符串传递给Reflection方法,而DLR会自动使用反射来进行调用.否则完全相同的编程工作,你必须知道字符串.
后期绑定的主要优点是它对版本控制具有弹性,这是第三方支持它的基本原因.但它的主要缺点是,如果你没有一本好的手册或者版本变化太多,那么你会得到一个令人讨厌的运行时异常,除了"它没有用"之外什么都不告诉你.编译器无法帮助您正确完成,它不知道类型.IntelliSense无法帮助您,它无法提供任何自动完成功能.只是在运行时爆炸,找出问题的唯一方法是翻阅(缺失)手册或与程序员交谈.
许多COM组件都支持早期和晚期绑定.您需要一个类型库来使用早期绑定,它是组件支持的接口和coclass的机器可读描述.它与.NET程序集中的元数据完全等效.并执行相同的角色,使用类型库,编译器现在可以检查您的代码,IntelliSense可以提供自动完成.
类型库通常嵌入在可执行文件(.dll或.exe)中,有时它作为单独的文件传递,.tlb和.olb是常见的扩展名.您可以使用Visual Studio的文件>打开>文件查看可执行文件,如果嵌入了类型库,您将看到TYPELIB节点.然后,您可以使用OleView.exe,File> View Typelib命令查看其内容.并运行Tlbimp.exe以生成互操作库.
如果您找不到类型库并且没有合适的最新编程手册,那么只有电话可以帮助您.致电组件的所有者或作者以获取帮助.
如果您的“ClassName”是 COM 可见的,您应该能够使用基本类型转换来转换返回的 com 对象。
Type ComClassType = SomeDLLAssembly.GetType("ClassName");
ClassName myInstance = (ClassName)icf2.CreateInstanceLic(null, null, ComClassType.GUID, "License string");
myInstance.ComClassMethod();
Run Code Online (Sandbox Code Playgroud)