2015-09-21 8 views
8

में मैं Getter और Setter तरीकों के लिए प्रतिनिधि बनाकर मेरा प्रतिबिंब कोड बेहतर बनाने की कोशिश कर रहा हूँ।एक कार्रवाई <T> या समारोह <T> में एक प्रतिनिधि कास्टिंग क्रम

मेरे कोड इस तरह दिखता है:

MyObject obj = new MyObject(); 
var prop = obj.GetType().GetProperty("Prop"); 
var getType = typeof(Func<>).MakeGenericType(prop.PropertyType); 
var setType = typeof(Action<>).MakeGenericType(prop.PropertyType); 

var getMethod = prop.GetGetMethod().CreateDelegate(getType, obj); 
var setMethod = prop.GetSetMethod().CreateDelegate(setType, obj); 

// I'd like to change this section and not to use a dynamic!! 
dynamic castedGet = Convert.ChangeType(getMethod, getType); 
dynamic castedSet = Convert.ChangeType(setMethod, setType); 

CreateDelegate रिटर्न एक Delegate और DynamicInvoke का उपयोग कर प्रदर्शन समझदारी नहीं है।

मैंने Delegate को Action<T> \ Func<T> में डाला (हार्डकोड किया) और मेरे प्रदर्शन में भारी वृद्धि देखी।

मैं तो (Convert.ChangeType और dynamic का प्रयोग करके) क्रम में Action<T> \ Func<T> में Delegate कास्ट करने के लिए कोशिश की और मेरे प्रदर्शन चोट लगी - शायद इस तथ्य है कि मैं एक dynamic प्रकार उपयोग कर रहा हूँ की वजह से।

मुझे पूरा यकीन है कि मैं dynamic के बिना ऐसा कर सकता हूं।

मुझे लगता है कि समाधान expression trees के साथ कुछ है, लेकिन मैं वास्तव में कुछ इस तरह कोड करने के लिए कैसे यकीन नहीं है। अगर किसी के पास कोई अच्छा समाधान है जो expression trees का उपयोग नहीं करता है, तो इसके बारे में भी सुनना दिलचस्प होगा।

+0

क्या आप इस कोड * हर * समय को निष्पादित कर रहे हैं, या प्रतिनिधियों को कहीं और कैश कर रहे हैं और फिर उन्हें बुला रहे हैं? – Dai

+0

@ दाई - यह मेरे कोड का एक छोटा सा हिस्सा है और एक नमूना है। मैं एक आलसी तरीके से - प्रत्येक संपत्ति के लिए propertyinfo, गेटर, सेटर कैश करने के लिए देख रहा हूँ। –

+0

फिर भी आप 'गतिशील' का उपयोग क्यों कर रहे हैं? 'कनवर्ट करें। चेंज टाइप' देर से बाध्य वस्तु वापस नहीं करता है। – Dai

उत्तर

3

उपयोग कर सकते हैं यदि नहीं अपने उद्देश्य संकलन समय पर वापसी प्रकार जानने के बिना अपनी कार्रवाई/समारोह आह्वान करने के लिए सक्षम होने के लिए है, तो आप शायद अंत करना चाहते हैं Action<object> और Func<object> के साथ, है ना?

आप एक अभिव्यक्ति पेड़ या कुछ भी संकलन इतना की तरह बिना ऐसा कर सकते हैं:

private static Action<object> CastAction<T>(Delegate d) 
{ 
    var action = (Action<T>)d; 
    return obj => action((T)obj); 
} 

मेरे परीक्षण यह दिखाने मोटे तौर पर 25% तेजी से होने के लिए:

// Use reflection to create the action, invoking the method below. 
var setAction = (Action<object>) this.GetType() 
    .GetMethod("CastAction", BindingFlags.Static | BindingFlags.NonPublic) 
    .MakeGenericMethod(prop.PropertyType) 
    .Invoke(null, new object[]{setMethod}); 

// invoke the action like this: 
object value = 42; // or any value of the right type. 
setAction(value); 

इस सहायक पद्धति का उपयोग करना dynamic का उपयोग करने से, और केवल obj.Prop = 2 कहने से लगभग 45% धीमी है;

+0

का उपयोग करके 'Invoke() 'ducktyping से धीमा है @ k3b उत्तर के बीच क्या अंतर है? ओपी ने कहा कि "MethodInfo.Invoke का उपयोग प्रतिनिधियों को बनाने और उन्हें आमंत्रित करने से बहुत धीमा है" –

+0

@ कोडोडिपो: इस मामले में, मैं केवल पहली जगह में प्रतिनिधि बनाने के लिए 'MethodInfo.Invoke()' का उपयोग कर रहा हूं। यह कुछ ऐसा है जो ओपी की 'चेंज टाइप' विधि प्रभावी रूप से कवर के तहत कर रही है। परिणामी 'setAction' क्रिया, हालांकि,' setter.Invoke() 'को कॉल करने से कहीं अधिक तेज़ी से लागू की जा सकती है, क्योंकि के 3 बी का उत्तर करता है। और यह गतिशील 'जालीसेट' कार्रवाई को कॉल करने से कुछ हद तक तेज है, क्योंकि यह गतिशील आमंत्रण पर निर्भर नहीं है। – StriplingWarrior

+1

@StriplingWarrior - यह बहुत दिलचस्प है। हार्ड कोडित कास्टिंग का उपयोग करने से गतिशील और धीमी गति से उपयोग करने से बेंचमार्क बेहतर होते हैं। वर्तमान में यह मेरे पास सबसे तेज़ सामान्य तरीका है। आपके उत्तर के लिए धन्यवाद। मैं कुछ और उत्तरों की प्रतीक्षा कर रहा हूं और अगर कुछ भी बेहतर नहीं है तो मैं स्वीकार करूंगा। धन्यवाद!!!! +1। –

1

क्या कोई कारण है कि आपको एक्शन < टी> या Func < टी> को गतिशील रूप से प्रोपेरी प्राप्त करने/सेट करने के लिए उपयोग करने की आवश्यकता है?

आप PropertyInfo.GetMethod() और SetMethod()

MyObject obj = new MyObject(); 
PropertyInfo prop = obj.GetType().GetProperty("Prop"); 

MethodInfo getter = prop.GetMethod(); 
getter.Invoke(...) 

MethodInfo setter = prop.SetMethod(); 
setter.Invoke(...) 
+0

कारण प्रदर्शन है। MethodInfo.Invoke का उपयोग प्रतिनिधियों को बनाने और उन्हें आमंत्रित करने से बहुत धीमा है (मान लीजिए कि मैं उन्हें कैश करना चाहता हूं)। फिर भी धन्यवाद। –

+1

मुझे पता नहीं था (और कभी नहीं सोचा और खुद को कभी नहीं देखा) कि 'गतिशील' – k3b

संबंधित मुद्दे