2009-11-22 10 views
8

मैं एक गतिशील रूप से जेनरेट किए गए एक आंतरिक विधि का आह्वान करने की कोशिश कर रहा हूं। आईएल कोड सरल है: ldarg_0, callvirt, ret।क्या .NET में गतिशील विधि से आंतरिक विधि का आह्वान करना संभव है?

विधि को निष्पादित करना TypeLoadException के साथ विफल रहता है और कह रहा है कि यह उस प्रकार को लोड नहीं कर सकता जिस पर आंतरिक विधि परिभाषित की गई है।

जब मैं इसके बारे में सोचता हूं, यह तार्किक लगता है, क्योंकि गतिशील विधि होस्ट असेंबली विधि की घोषणा प्रकार असेंबली का मित्र नहीं है।

हालांकि, मैंने उम्मीद की है कि डायनामिक विधि अभी भी काम करने के लिए है, जैसे Delegate.CreateDelegate काम करता है। आखिरकार, मैंने आंतरिक विधि के MethodInfo प्राप्त करने का प्रबंधन किया, इसलिए अनुमति अवरोध मेरे पीछे है।

वैसे भी, सवाल यह है कि "गतिशील रूप से जेनरेट किए गए एक आंतरिक विधि को एक आंतरिक विधि का आह्वान करना संभव है?"

धन्यवाद।

संपादित करें:

using System; 
using System.Linq.Expressions; 
using System.Reflection; 
using System.Reflection.Emit; 

namespace A 
{ 
    internal class Data 
    { 
    internal string String { get; set; } 
    } 

    public static class Program 
    { 
    public static void Main() 
    { 
     Expression<Func<Data, string>> expr = x => x.String; 
     var getterInfo = ((PropertyInfo)((MemberExpression)expr.Body).Member).GetGetMethod(true); 
     var getter1 = (Func<Data, string>)Delegate.CreateDelegate(typeof(Func<Data, string>), getterInfo); 
     var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }); 
     var gen = dm.GetILGenerator(); 
     gen.Emit(OpCodes.Ldarg_0); 
     gen.Emit(OpCodes.Castclass, typeof(Data)); 
     gen.Emit(OpCodes.Callvirt, getterInfo); 
     gen.Emit(OpCodes.Ret); 
     var getter2 = (Func<object, object>)dm.CreateDelegate(typeof(Func<object, object>)); 

     var data = new Data() { String = "Hello" }; 
     var str1 = getter1(data); 
     var str2 = getter2(data); 
    } 
    } 
} 

कोड में मैं Data.String उदाहरण संपत्ति का उपयोग करने के दो खुले उदाहरण प्रतिनिधियों बनाने:

यहाँ एक सरल कोड समस्या का प्रदर्शन नमूना है

  • Delegate.CreateDelegate
  • प्रकार का उपयोग कर सुरक्षित गेटर 1 टाइप करें afe getter2 DynamicMethod

प्रकार सुरक्षित Delegate.CreateDelegate द्वारा बनाई प्रतिनिधि काम करता है का उपयोग कर, DynamicMethod का उपयोग कर एक TypeLoadException के साथ विफल हो रही है।

नोट, कि मैं प्रकार सुरक्षित दृष्टिकोण नहीं लेना चाहता हूं, क्योंकि संदर्भ जहां गेटटर बनाया गया है वह सामान्य नहीं है। बेशक, मैं इस मुद्दे को हल कर सकता हूं, लेकिन सवाल अब प्रिंसिपल का है - डायनामिक मोड क्यों विफल रहता है जहां प्रतिनिधि। क्रिएटडिलेट सफल होता है?

+0

एक टाइपलोड लोड अपवाद का तात्पर्य है कि असेंबली नहीं मिल सकती - फ़्यूज़न लॉग व्यूअर क्या कहता है? –

+0

फ़्यूज़न लॉग खाली है। असेंबली लोड करने में कोई समस्या नहीं होनी चाहिए। सभी शामिल असेंबली एक ही फ़ोल्डर में स्थित हैं। – mark

+0

@ जेरेमीएमसीजी सही है। डीबग मोड के दौरान AppDomain में लोड असेंबली की सूची प्राप्त करें और चेक वहां लक्षित असेंबली है। साथ ही, जांचने के लिए अपना कोड यहां रखना बेहतर है। –

उत्तर

6

यदि आप दृश्यता जांच छोड़ते हैं तो यह काम करेगा।

बदलें इस लाइन

var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }, true); 

msdn देखें: (। सभी नियमों के साथ विशेष रूप से तालिका में)

यह निर्माता पर doco से है।

restrictedSkipVisibility प्रकार: System.Boolean प्रकार और सदस्यों गतिशील विधि के MSIL द्वारा पहुँचा पर JIT दृश्यता चेकों को छोड़ने के लिए सही है, इस प्रतिबंध के साथ: विधानसभाओं के विश्वास स्तर है कि उन शामिल प्रकार और सदस्यों को ट्रस्ट कॉल के स्तर के बराबर या उससे कम होना चाहिए जो गतिशील विधि को उत्सर्जित करता है; अन्यथा, झूठी।

+0

DynamicMethod .NET मानक में नहीं है, .NET मानक में ऐसा करने का कोई तरीका है? – trampster