2011-11-10 18 views
6

Ben genel bir özellik değerini ayarlamak için bir temsilci oluşturun çalışıyorum, ancak bir hata alıyorum:Delege için Jenerik Property.GetSetMethod

Action<T, object> setValue = (Action<T, object>) Delegate.CreateDelegate(
    typeof(Action<T, object>), null, property.GetSetMethod()); 

mi: Aşağıdaki kodu çalıştırmak çalıştığınızda Error binding to target method Bu mümkün mü?

+0

Mülkiyetiniz statik bir özellik midir? Eğer değilse, o zaman boş olamaz. – phoog

+0

Hayır değil, üzgünüm o parçayı özledim, ama sınıfın bir örneğini geçtiğimde bile düzgün çalışmıyorsa, yine de aynı istisnayı elde ediyorum – ChandlerPelhams

cevap

3

Evet, yalnızca yanlış türde bir temsilci oluşturmaya çalışıyorsunuzdur. Bir mülkün ayarlanmış yöntemi sadece bir argüman alır, sizin belirleyeceğiniz değer. Ayrıca bir örnek yöntemi olduğundan, CreateDelegate çağrısında bağlı olmasını istediğiniz hedef nesneyi geçirmeniz gerekir.

Örnek:

var setValue = (Action<T>)Delegate.CreateDelegate(typeof(Action<T>), target, property.GetSetMethod()); 
1

Bunu istiyorum düşünüyorum:

Action<T, object> setValue = (t, o) => property.GetSetMethod().Invoke(t, new object[] { o }); 

veya

Action<T, object> setValue = (t, o) => property.SetValue(t, o, null); 

DÜZENLEME

bu yöntemi varsayalım, kabul edilen yanıt ile karşılaştırıldığında bu cevabın kabul yoksul performans göstermek için :

void SetAnObjectPropertyOnALotOfObjects<T>(IEnumerable<T> objs) 
{ 
    //Create a delegate and assign a reference to that delegate to the setValue variable 
    Action<T, object> setValue = GetSetter(); 

    foreach (var o in objs) 
    { 
     //invoke the delegate referred to by the setValue variable (that is, "invoke its referent" 
     setValue.Invoke(o, new object()); 
    } 
} 

MerickOWA'nın yanıtı, GetSetter yönteminde yansıma kullanır; dolayısıyla, yaklaşımında, GetSetter yönteminin yürütülmesi için daha fazla zaman harcadığını varsayarız. Bu cevap, setValue.Invoke aradığımız her seferinde yansımayı kullanır, bu nedenle bu cevabın yürütülmesi için daha fazla zaman gerektiğini varsayarız. Sıradaki öğelerin sayısının büyük olduğunu varsayarsak, MerickOWA'nın cevabı yürütmek için daha az zaman gerektirir.

Örneğin, MerickOWA'nın GetSetter yönteminin, yürütmemden X milisaniye daha fazla süre aldığını ve setValue temsilcisinin Y milisaniyesini kendisinden daha fazla aldığını varsayalım. Sırada N öğesi varsa, benim çözümüm (N * Y - X) milisaniye tarafından daha yavaş olmalıdır.

+0

Değeri her seferinde ayarlamak için PropertyInfo kullanır, bu çok daha yavaştır CreateDelegate, – MerickOWA

+0

Ah döndürdüğünden daha fazla, elbette (kafamı tokatlamak) – phoog

+0

Bu yöntemin neden daha yavaş olacağını söyler misiniz? Testlerimde, lambda, temsilci oluşturmanın yarısında gerçekleştirildi. – nawfal

1

Duruma göre. Benim cevap olarak iki şey varsayalım: (

  1. Tipin "T" (Ben şimdi TClass olarak ifade edecektir) sınıfın tipi
  2. türü "nesne" mülkünüzün türüdür olan mülkünüz olmayan bir statik olduğundan Şimdi iki possibilies vardır) TProperty olarak

ifade edecektir:

  1. ekli hedefin (örnek) ile bir "normal" bir temsilci.
  2. Delegenin ilk giriş parametresi olarak bir hedefin gerekli olduğu bir "açık" temsilci.
    static public Action<TClass, TProperty> CreateSetPropertyDelegate<TClass, TProperty>(this PropertyInfo propertyInfo) 
    { 
        return (Action<TClass, TProperty>)Delegate.CreateDelegate(typeof(Action<TClass, TProperty>), propertyInfo.GetSetMethod()); 
    } 
    

    ve kullanımda

    (özelliği türü varsayarak int türünde):

    Action<int> setter = typeof(MyClass).GetProperty("MyProperty").CreateSetPropertyDelegate<MyClass, int>(myInsance); 
    setter(myPropertyValue); 
    

    bir fonksiyon aşağıdaki gibi

"Normal" temsilci oluşturmak için bir fonksiyon oluşturulur Açık bir temsilci oluşturmak için:

Ve kullanımda:

Action<MyClass, int> setter = typeof(MyClass).GetProperty("MyProperty").CreateSetPropertyDelegate<MyClass, int>(); 
setter(myInsance, myPropertyValue);