我正在使用動態實例化SoapHttpClientProtocol
對象(代理類)的代碼,並使用此對象來調用WS-Basic I Web Service。這是我的代碼的簡化版本:
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:嘗試訪問缺少的成員。
我在代碼中遺漏了什麼嗎?
謝謝!
Expression.Lambda(Expression.New(constructorInfo)).Compile()
部分返回一個Func<T>
委託,它包裝存儲在callingObject
參數中的Type
callingObject
函數。要實際調用該構造函數,您仍需要調用它:
Delegate delegateWithConstructor = Expression.Lambda(Expression.New(constructorInfo)).Compile();
object instance = delegateWithConstructor.DynamicInvoke();
但是,從長遠來看,你要做的事情似乎很奇怪和脆弱,因為你將方法名稱作為簡單的字符串和參數傳遞給對象,因此失去所有編譯時類型檢查。你為什麼需要這樣做?