2012-07-26 20 views
5

我正在使用動態實例化代碼SoapHttpClientProtocol object(代理類)並使用此對象調用WS-Basic I Web Service。這裏是我的代碼的簡化版本:使用編譯的Lambda表達式而不是Activator.CreateInstance初始化SoapHttpClientProtocol對象

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()通話可能需要很長時間顯著量,所以我想對代碼進行優化by using a lambda expression

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:試圖訪問缺少的成員。

我在代碼中丟失了什麼嗎?

謝謝!

+0

鏈接是死的順便 – NStuke 2017-10-20 00:34:09

回答

3

Expression.Lambda(Expression.New(constructorInfo)).Compile()部分返回一個Func<T>委託,該委託包含存儲在callingObject參數中的構造函數Type。要真正通話這個構造函數,你仍然需要調用它:

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

但是,你正在嘗試做似乎從長遠來看很奇怪和脆弱的,因爲你是在繞過方法名作爲簡單的字符串和參數作爲對象,因此會丟失所有編譯時類型檢查。你爲什麼需要這樣做?

+0

+1,簡單而簡單。但爲什麼要把'Delegate'放回去做動態調用?爲什麼不只是'Func'然後()? – nawfal 2013-04-26 13:50:06

0

使用表達式樹會導致程序運行速度變慢,除非您緩存已編譯的表達式。

相關問題