在.NET中,COM互操作技术允许调用COM组件中的方法。这项技术自.NET首次发布以来就存在,因此在使用时通常不会遇到太多困难。具体来说,假设有一个简单的VB6COM对象"MyProject.MyClass",它包含一个名为"Add"的方法,接受两个整数参数并返回它们的和:
Public Function Add(first As Integer, second As Integer) As Integer
Add = first + second
End Function
为了调用这个COM对象,首先在Visual Studio中创建了一个新的项目,并向其中添加了对COM对象的引用。然后,编写了以下代码:
using System;
namespace ComTest
{
class Program
{
static void Main(string[] args)
{
MyProject.MyClass comObject = new MyProject.MyClass();
short sum = comObject.Add(1, 2);
Console.Out.WriteLine("Early binding. Sum = " + sum);
Console.ReadLine();
}
}
}
这段代码能够正常工作。但是,随着时间的推移,发现第三方COM对象几乎每月都会更新一次。由于这个COM对象可能是用VB6开发的,并且没有设置版本兼容性,即使接口签名没有变化,GUID也会不断变化。结果,程序开始崩溃,并显示以下错误消息:
"An unhandled exception of type 'System.InvalidCastException' occurred in ComTest.exe"
面对这种情况,有两个选择:要么每次收到新的COM对象时重新编译Web服务,要么使用晚期绑定。显然,选择了后者。C#代码如下所示:
using System;
using System.Reflection;
namespace ComTest
{
class Program
{
static void Main(string[] args)
{
System.Type objType = System.Type.GetTypeFromProgID("MyProject.MyClass");
object comObject = System.Activator.CreateInstance(objType);
object[] oParms = new Object[] { 1, 2 };
short sum = (short)objType.InvokeMember("Add", BindingFlags.InvokeMethod, null, comObject, oParms);
Console.Out.WriteLine(sum);
Console.ReadLine();
}
}
}
using System;
using System.Reflection;
namespace ComTest
{
class Program
{
static void Main(string[] args)
{
System.Type objType = System.Type.GetTypeFromProgID("MyProject.MyClass");
dynamic comObject = System.Activator.CreateInstance(objType);
short sum = comObject.add(1, 2);
Console.Out.WriteLine("Late binding with dynamic type. Sum = " + sum);
Console.ReadLine();
}
}
}