2011-11-10 13 views
6

मैं एक सामान्य की एक संपत्ति के मूल्य की स्थापना के लिए एक प्रतिनिधि बनाने के लिए कोशिश कर रहा हूँ, लेकिन मैं एक त्रुटि हो रही है:प्रतिनिधि के लिए जेनेरिक Property.GetSetMethod

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

है: जब मैं निम्नलिखित कोड निष्पादित करने के लिए कोशिश Error binding to target method यह भी संभव है?

+0

क्या आपकी संपत्ति एक स्थिर संपत्ति है? यदि नहीं, तो आप शून्य से गुजर नहीं सकते हैं। – phoog

+0

नहीं, यह नहीं है, माफ करना, मैंने उस टुकड़े को याद किया, लेकिन जब भी मैं कक्षा के उदाहरण में जाता हूं, यह सही तरीके से काम नहीं करता है, मुझे अभी भी एक ही अपवाद मिलता है – ChandlerPelhams

उत्तर

3

हां यह संभव है, आप बस गलत प्रकार के प्रतिनिधि को बनाने की कोशिश कर रहे हैं। किसी प्रॉपर्टी की सेट विधि केवल एक तर्क लेती है, वह मान जिसे आप सेट करने जा रहे हैं। इसके अलावा एक उदाहरण विधि के बाद, आपको उस लक्ष्य ऑब्जेक्ट को पास करना होगा जिसे आप CreateDelegate कॉल में बाध्य करना चाहते हैं।

उदाहरण:

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

मुझे लगता है कि आप इस हैं:

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

या

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

संपादित

इस जवाब को स्वीकार कर लिया जवाब की तुलना में ग्रहण गरीब प्रदर्शन समझाने के लिए, इस विधि मान :

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

मरिकोवा का जवाब GetSetter विधि में प्रतिबिंब का उपयोग करता है, इसलिए हम मानते हैं कि GetSetter विधि को उसके दृष्टिकोण में निष्पादित करने में अधिक समय लगता है। यह जवाब प्रत्येक बार प्रतिबिंब का उपयोग करता है जब हम setValue.Invoke पर कॉल करते हैं, इसलिए हम मानते हैं कि इस उत्तर में निष्पादित करने में अधिक समय लगता है। अगर हम मानते हैं कि अनुक्रम में वस्तुओं की संख्या बड़ी है, तो मरिकोवा के उत्तर को निष्पादित करने के लिए कम समय की आवश्यकता होनी चाहिए।

उदाहरण के लिए, मान लीजिए कि मेरिकोवा की गेटसेटर विधि निष्पादित करने के लिए एक्स मिलीसेकंड अधिक लेती है, जबकि मेरा सेट वैल्यू प्रतिनिधि अपने से अधिक वाई मिलीसेकंड लेता है। यदि अनुक्रम में एन आइटम हैं, तो मेरा समाधान उसके (एन * वाई - एक्स) मिलीसेकंड से धीमा होना चाहिए।

+0

यह हर बार मूल्य निर्धारित करने के लिए PropertyInfo का उपयोग करता है, यह बहुत धीमा है CreateDelegate क्या होगा – MerickOWA

+0

आह, निश्चित रूप से (मेरे सिर को थप्पड़ मारना) – phoog

+0

क्या आप मुझे बता सकते हैं कि यह विधि धीमी क्यों होगी? मेरे परीक्षणों में, लैम्ब्डा प्रतिनिधि बनाने के आधा समय में प्रदर्शन किया। – nawfal

1

यह निर्भर करता है। मेरा उत्तर में मैं दो बातें मान:

  1. आपका प्रकार "टी" अपने वर्ग के प्रकार (जो मैं अब TClass के रूप में निरूपित जाएगा)
  2. प्रकार "वस्तु" अपनी संपत्ति के प्रकार है (जो क्योंकि अपनी संपत्ति एक गैर स्थिर है मैं अब TProperty के रूप में निरूपित जाएगा)

, दो possibilies देखते हैं:

  1. संलग्न लक्ष्य (उदाहरण) के साथ एक "सामान्य" प्रतिनिधि।
  2. एक "खुला" प्रतिनिधि जिसमें प्रतिनिधि के पहले इनपुट पैरामीटर के रूप में एक लक्ष्य की आवश्यकता होती है।

    static public Action<TClass, TProperty> CreateSetPropertyDelegate<TClass, TProperty>(this PropertyInfo propertyInfo) 
    { 
        return (Action<TClass, TProperty>)Delegate.CreateDelegate(typeof(Action<TClass, TProperty>), propertyInfo.GetSetMethod()); 
    } 
    

    और उपयोग में (संपत्ति प्रकार संभालने प्रकार int की है):

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

    एक समारोह

जैसे "सामान्य" प्रतिनिधि बनाने के लिए एक समारोह के रूप में निम्नानुसार बनाई गई है एक खुला प्रतिनिधि बनाने के लिए:

static public Action<TClass, TProperty> CreateSetPropertyDelegate<TClass, TProperty>(this PropertyInfo propertyInfo) 
{ 
    return (Action<TClass, TProperty>)Delegate.CreateDelegate(typeof(Action<TClass, TProperty>), propertyInfo.GetSetMethod()); 
} 

और उपयोग में:

Action<MyClass, int> setter = typeof(MyClass).GetProperty("MyProperty").CreateSetPropertyDelegate<MyClass, int>(); 
setter(myInsance, myPropertyValue); 
संबंधित मुद्दे