2009-08-18 13 views
5

मैं ऐसे प्रतिनिधि के लिए डायनामिक मोड को कैसे परिभाषित करूं जिसमें out -parameter है, इस तरह?डायनामिक मोड और आउट-पैरामीटर?

public delegate void TestDelegate(out Action a); 

चलो कहते हैं कि मैं बस एक तरीका है कि null को a तर्क सेट जब मैं विधि कॉल चाहते हैं।

ध्यान दें कि मुझे पता है कि इसे संभालने का शायद एक बेहतर तरीका यह तरीका है कि विधि Action प्रतिनिधि को वापस कर दे, लेकिन यह एक बड़ी परियोजना का एक सरल हिस्सा है, और प्रश्न में विधि पहले से ही एक मूल्य लौटाती है, मैं इसके अलावा out पैरामीटर को संभालने की आवश्यकता है, इसलिए सवाल।

using System; 
using System.Text; 
using System.Reflection.Emit; 

namespace ConsoleApplication8 
{ 
    public class Program 
    { 
     public delegate void TestDelegate(out Action a); 

     static void Main(String[] args) 
     { 
      var method = new DynamicMethod("TestMethod", typeof(void), 
       new Type[] { typeof(Action).MakeByRefType() }); 
      var il = method.GetILGenerator(); 

      // a = null; 
      il.Emit(OpCodes.Ldnull); 
      il.Emit(OpCodes.Starg, 0); 

      // return 
      il.Emit(OpCodes.Ret); 

      var del = (TestDelegate)method.CreateDelegate(typeof(TestDelegate)); 
      Action a; 
      del(out a); 
     } 
    } 
} 

हालांकि, मैं इस मिल:

मैं इस कोशिश की del(out a); लाइन पर

VerificationException was unhandled: 
Operation could destabilize the runtime. 

ध्यान दें कि यदि मैं दो पंक्तियों को टिप्पणी करता हूं जो ढेर पर एक नल लोड करते हैं और इसे तर्क में संग्रहीत करने का प्रयास करते हैं, तो विधि अपवादों के बिना चलता है।


संपादित: इस का सबसे अच्छा तरीका है?

il.Emit(OpCodes.Ldarg_0); 
il.Emit(OpCodes.Ldnull); 
il.Emit(OpCodes.Stind_Ref); 
+0

क्या गतिशील विधि बनाने के लिए वास्तव में इसकी आवश्यकता है? क्यों न केवल उस वर्ग में विधि को लागू करें जिसे आप रनटाइम पर जो करना चाहते हैं उसे करने के लिए कॉन्फ़िगर किया जा सकता है? –

+0

यह वास्तव में एक गतिशील विधि होना है, यह तेजी से निष्पादित करने के लिए एक विशाल प्रतिबिंब-आधारित कॉल-पेड़ प्राप्त करने के लिए एक अंतिम-स्टॉप ऑप्टिमाइज़ेशन प्रयास है। अब तक गतिशील विधि दृष्टिकोण का उपयोग करने का उपर मौजूदा कोड का उल्लंघन लगभग 85% कम लगता है, और यह वह कोड है जिसे प्रत्येक सेकेंड में हजारों बार बुलाया जाएगा। मापन दर्शाते हैं कि मौजूदा प्रतिबिंब कोड में बहुत सी सीपीयू बांध ली गई है। –

उत्तर

6

एक out तर्क OutAttribute पैरामीटर के लिए लागू के साथ सिर्फ एक ref तर्क है।

बाय-रेफ तर्क को संग्रहीत करने के लिए, आपको stind ऑपोड का उपयोग करने की आवश्यकता है, क्योंकि तर्क स्वयं ऑब्जेक्ट के वास्तविक स्थान पर एक प्रबंधित सूचक है।

ldarg.0 
ldnull 
stind.ref 
संबंधित मुद्दे