2012-07-26 15 views
5

başlatmak için Activator.CreateInstance yerine Derlenmiş Lambda ifadesini kullan Dinamik olarak SoapHttpClientProtocol nesnesini (proxy sınıfı) başlatılan kodla çalışıyorum ve WS-Basic I Web Hizmeti'ne bir çağrı yapmak için bu nesneyi kullanıyorum. İşte benim kod basitleştirilmiş bir versiyonudur:SoapHttpClientProtocol nesnesini

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); 
} 

Bazı durumlarda Activator.CreateInstance() çağrı zaman önemli miktarda alabilir fark ettik, bu yüzden kod by using a lambda expression optimize etmek çalışıyorum:

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); 
} 

:

Maalesef bu kodu (bunun yerine bir Func<T> temsilci nesnesi döndürür) ve bu nedenle sonraki satırda Url ayarlamaya çalıştığında bir istisna atar callingObject türde bir nesne yaratmaz

System.MissingMethodException: Eksik bir üyesini erişmeye çalışıldı.

Am benim kodunda şey eksik?

Teşekkürler!

+0

Bağlantı yolu – NStuke

cevap

3

Expression.Lambda(Expression.New(constructorInfo)).Compile() bölümü, parametresinde saklanan Type yapıcıyı saran bir Func<T> temsilci döndürür. Için aslında çağrı bu yapıcı, yine de çağırmak gerekir: Ancak

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

, ne yapmaya çalışıyorsun, uzun vadede oldukça garip ve kırılgan görünüyor basit dizeleri olarak yöntem isimlerinin etrafında geçiyoruz beri ve nesneler olarak parametreler, dolayısıyla tüm derleme zamanı tipi kontrolünü kaybeder. Neden bunu yapmalısın?

+0

1, kısa ve basit tarafından öldü. Ama neden Delegeye geri dön ve dinamik bir iniş yap? Neden sadece 'Func' ve sonra()? – nawfal

0

İfade ağaçlarını kullanmak, derlenmiş ifadeyi önbelleğe almadığınız sürece programınızın yavaş çalışmasına neden olur.