6

我正在使用动态实例化SoapHttpClientProtocol对象(代理类)并使用该对象调用 WS-Basic I Web 服务的代码。这是我的代码的简化版本:

public override object Call(Type callingObject,
string method, object[] methodParams, string URL)
{
    MethodInfo requestMethod = callingObject.GetMethod(method);

    //creates an instance of SoapHttpClientProtocol
    object instance = Activator.CreateInstance(callingObject);

    //sets the URL for the object that was just created 
    instance.GetType().InvokeMember("Url", 
    BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty, null,
    instance,
    new object[1] {URL});

    return requestMethod.Invoke(instance, methodParams); 
}

我注意到在某些情况下Activator.CreateInstance()调用可能会花费大量时间,因此我尝试使用 lambda 表达式来优化代码:

public override object Call(Type callingObject,
string method, object[] methodParams, string URL)
{
    MethodInfo requestMethod = callingObject.GetMethod(method);

    //creates an instance of SoapHttpClientProtocol using compiled Lambda Expression
    ConstructorInfo constructorInfo = callingObject.GetConstructor(new Type[0]);
    object instance = Expression.Lambda(Expression.New(constructorInfo)).Compile();

    //sets the URL for the object that was just created 
    instance.GetType().InvokeMember("Url", 
    BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty, null,
    instance,
    new object[1] {URL});

    //calls the web service
    return requestMethod.Invoke(instance, methodParams); 
}

不幸的是,这段代码没有创建该callingObject类型的对象(而是返回一个Func<T>委托对象),因此当它试图Url在下一行中设置时,它会抛出一个异常:

System.MissingMethodException:试图访问缺少的成员。

我的代码中是否缺少某些内容?

谢谢!

4

2 回答 2

3

Expression.Lambda(Expression.New(constructorInfo)).Compile()部分返回一个Func<T>委托,该委托包装了Type存储在callingObject参数中的构造函数。要实际调用该构造函数,您仍然需要调用它:

Delegate delegateWithConstructor = Expression.Lambda(Expression.New(constructorInfo)).Compile();
object instance = delegateWithConstructor.DynamicInvoke();

但是,从长远来看,您尝试做的事情似乎非常奇怪和脆弱,因为您将方法名称作为简单的字符串和参数作为对象传递,因此丢失了所有编译时类型检查。为什么你需要这样做?

于 2012-07-26T19:27:43.200 回答
0

除非您缓存已编译的表达式,否则使用表达式树会导致程序运行速度变慢。

于 2012-07-30T09:21:12.473 回答