2011-11-14 10 views
24

मैं सी # में एएसटी को समझने की कोशिश कर रहा हूं। मुझे आश्चर्य है, इस उदाहरण से Compile() विधि क्या है।लैम्ब्डा अभिव्यक्ति संकलन() विधि क्या करता है?

// Some code skipped  
Expression<Func<string, int, int, string>> data = Expression.Lambda<Func<string, int, int, string>>( 
     Expression.Call(s, typeof(string).GetMethod(“Substring”, new Type[] { typeof(int), typeof(int) }), a, b), 
     s, a, b 
    ); 
Func<string, int, int, string> fun = data.Compile(); 

गलतफहमी रोकने के लिए, मैं Expression.Lambda और Expression.Call निर्माणों को समझते हैं। मुझे Compile() विधि क्या रूचि है। क्या यह किसी भी तरह असली एमएसआईएल का उत्पादन करता है? क्या मैं एमएसआईएल देख सकता हूं?

+0

एक प्रतिनिधि से एक प्रतिनिधि को प्राप्त करने के लिए आप कह सकते हैं कि आपको 'कंपाइल() ' – BrokenGlass

+0

ठीक है, और उस प्रतिनिधि के पीछे क्या है? –

+0

एक विधि (MethodInfo) – Jeff

उत्तर

44

मुझे Compile() विधि क्या रूचि है। क्या यह किसी भी तरह असली एमएसआईएल का उत्पादन करता है?

हां। संकलन विधि लैम्ब्डा बॉडी ब्लॉक पर एक आगंतुक चलाती है और प्रत्येक उप-संपीड़न के लिए आईएल गतिशील रूप से उत्पन्न करती है।

यदि आप खुद को आईएल को थूकना सीखने में रुचि रखते हैं, तो this "Hello World" example of how to use Lightweight Codegen देखें। (मुझे लगता है कि यदि आप आंशिक रूप से भरोसेमंद ऐपडोमेन में लाइटवेट कोडेजन का उपयोग करने की दुर्भाग्यपूर्ण स्थिति में हैं, तो चीजें प्रतिबंधित छोड़ने वाली दृश्यता वाली दुनिया में थोड़ा अजीब हो सकती हैं; यदि आप रुचि रखते हैं तो इस विषय पर Shawn Farkas's article देखें।)

क्या मैं एमएसआईएल देख सकता हूं?

हां, लेकिन आपको एक विशेष "विज़ुअलाइज़र" की आवश्यकता है।

http://blogs.msdn.com/b/haibo_luo/archive/2005/10/25/484861.aspx

+2

बहुत प्रभावशाली, हालांकि यह थोड़ी सी मेरे सिर को चोट पहुंचाता है। –

7

एक अभिव्यक्ति एक अभिव्यक्ति वृक्ष के रूप में एक डेटा संरचना का प्रतिनिधित्व करती है - Compile() का उपयोग करके इस अभिव्यक्ति पेड़ को एक प्रतिनिधि के रूप में निष्पादन योग्य कोड में संकलित किया जा सकता है (जो एक "विधि" कॉल है)।

संकलन के बाद आप आम तौर पर प्रतिनिधि को आमंत्रित कर सकते हैं - आपके उदाहरण में प्रतिनिधि Func<string,int,int,string> है। इस दृष्टिकोण की आवश्यकता हो सकती है जब आप गतिशील रूप से उस डेटा के आधार पर अभिव्यक्ति वृक्ष बनाते हैं जो केवल संबंधित समय को बनाने और निष्पादित करने के अंतिम लक्ष्य के साथ रन टाइम पर उपलब्ध होता है।

आप प्रतिनिधि के लिए "कोड" नहीं देख सकते हैं। अभिव्यक्ति वृक्ष जिस पर आधारित है वह उस के सबसे नज़दीक है।

+0

धन्यवाद! जो भी मुझे अभी भी समझ में नहीं आता है, प्रतिनिधि को कैसे निष्पादित किया जा सकता है। मुझे लगता है कि वहाँ बाइटकोड होना चाहिए, कहीं ... –

+0

शायद ऑफ-विषय, लेकिन मुझे आश्चर्य है कि इस आईएल को गतिशील रूप से उत्पन्न करने के लिए प्रदर्शन दंड क्या है। –

0

इसका जवाब अब आंशिक रूप से पुरानी हो चुकी है, जबकि इसमें अब केवल कभी कभी क्या होता है: विजुआलाइज़र मैं इसे यहाँ डाउनलोड किया जा सकता की Compile() डिबग करने के लिए है, जबकि मैं अपने अंश को लागू किया गया था इस्तेमाल किया।

आईएल को अभिव्यक्तियों के संकलन के लिए प्रतिबिंब की आवश्यकता होती है। स्वीकार करें जो हर समय उपलब्ध नहीं है, विशेष रूप से एओटी के साथ। तो उन मामलों में आईएल को संकलित करने के बजाय अभिव्यक्तियों का प्रतिनिधित्व करने वाली वस्तुओं की सूची में "संकलित" है। इन निर्देशों में से प्रत्येक में Run विधि है जो आईएल के रूप में मूल्यों के ढेर पर काम करने के लिए उचित कार्रवाई करने का कारण बनती है। इन ऑब्जेक्ट्स पर Run पर कॉल करने वाली विधि को प्रतिनिधि के रूप में वापस किया जा सकता है।

आम तौर पर ऐसे प्रतिनिधि को चलाने से आईएल को जुटाने से धीमा होता है, लेकिन आईएल के संकलन के दौरान यह एकमात्र विकल्प उपलब्ध नहीं है, और संकलन चरण अक्सर तेज़ होता है, इसलिए अक्सर संकलन + रन का कुल समय कम होता है एक बंद अभिव्यक्ति के लिए आईएल के साथ दुभाषिया।

इसी कारण से, में।नेट कोर अब Compile का ओवरलोड है जो आईओएल को संकलित करने के बावजूद एक बूलियन व्याख्या का अनुरोध करता है।

जो सभी भाषाओं के दिलचस्प मिश्रण के लिए बनाता है; अभिव्यक्ति स्वयं एक भाषा है, असेंबली सी # में लिखी गई है, यह आईएल को संकलित कर सकती है और व्याख्या की गई निर्देश वस्तुएं चौथी भाषा का गठन करती हैं।

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

  • कोई संबंधित समस्या नहीं^_^