डमी के लिए अभिव्यक्ति पेड़? [बन्द है]


83

मैं इस परिदृश्य में डमी हूं।

मैंने Google पर पढ़ने की कोशिश की है कि ये क्या हैं लेकिन मुझे अभी नहीं मिला है। क्या कोई मुझे बता सकता है कि वे क्या हैं और क्यों उपयोगी हैं?

संपादित करें: मैं .Net में LINQ सुविधा के बारे में बात कर रहा हूँ।


1
मुझे पता है कि यह पोस्ट पुरानी है, लेकिन मैं हाल ही में अभिव्यक्ति पेड़ों में देख रहा हूं। जब मैंने धाराप्रवाह NHibernate का उपयोग करना शुरू किया तो मुझे दिलचस्पी हो गई। जेम्स ग्रेगरी बड़े पैमाने पर स्थैतिक प्रतिबिंब के रूप में जाना जाता है और वह एक परिचय है: jagregory.com/writings/introduction-to-static-reflection स्थिर प्रतिबिंब और अभिव्यक्ति पेड़ों को कार्रवाई में देखने के लिए, धाराप्रवाह NHiberate स्रोत कोड ( fluentnhibernate.org देखें) )। यह बहुत साफ है, और एक बहुत अच्छी अवधारणा है।
जिम स्कुबर्ट

जवाबों:


89

मैंने कभी पढ़ा अभिव्यक्ति पेड़ के बारे में सबसे अच्छा विवरण चार्ली कैलवर्ट का यह लेख है।

इसका सारांश प्रस्तुत करना;

एक अभिव्यक्ति ट्री का प्रतिनिधित्व करता है कि आप क्या करना चाहते हैं, न कि आप कैसे करना चाहते हैं।

निम्नलिखित बहुत सरल मेमने की अभिव्यक्ति पर विचार करें:
Func<int, int, int> function = (a, b) => a + b;

इस कथन में तीन खंड हैं:

  • एक घोषणा: Func<int, int, int> function
  • एक बराबर ऑपरेटर: =
  • एक लंबोदर अभिव्यक्ति: (a, b) => a + b;

चर functionनिष्पादन योग्य कच्चे कोड पर बताता है कि दो संख्याओं को कैसे जोड़ा जाए

यह प्रतिनिधियों और अभिव्यक्तियों के बीच सबसे महत्वपूर्ण अंतर है। आप कभी भी function(a Func<int, int, int>) बिना यह जाने कि यह आपके द्वारा पास किए गए दो पूर्णांकों के साथ क्या करेगा। यह दो लेता है और एक लौटता है, यह आपके कोड को पता चल सकता है।

पिछले अनुभाग में, आपने देखा कि कच्चे निष्पादन योग्य कोड पर एक चर को कैसे घोषित किया जाए। अभिव्यक्ति के पेड़ निष्पादन योग्य कोड नहीं हैं , वे डेटा संरचना का एक रूप हैं।

अब, प्रतिनिधियों के विपरीत, आपका कोड पता कर सकता है कि अभिव्यक्ति का पेड़ क्या करना है।

LINQ एक डेटा संरचना में कोड का अनुवाद करने के लिए एक सरल वाक्यविन्यास प्रदान करता है जिसे एक अभिव्यक्ति ट्री कहा जाता है। पहला कदम Linq.Expressionsनाम स्थान को पेश करने के लिए एक उपयोग कथन जोड़ना है :

using System.Linq.Expressions;

अब हम एक अभिव्यक्ति ट्री बना सकते हैं:
Expression<Func<int, int, int>> expression = (a, b) => a + b;

पिछले उदाहरण में दिखाई गई समान लैम्ब्डा अभिव्यक्ति को अभिव्यक्ति के पेड़ में बदल दिया जाता है जो प्रकार का होता है Expression<T>। पहचानकर्ता निष्पादन योग्य कोड expression नहीं है ; यह एक डेटा संरचना है जिसे एक्सप्रेशन ट्री कहा जाता है।

इसका मतलब है कि आप सिर्फ एक अभिव्यक्ति पेड़ को आमंत्रित नहीं कर सकते हैं जैसे आप एक प्रतिनिधि को आमंत्रित कर सकते हैं, लेकिन आप इसका विश्लेषण कर सकते हैं। तो चर का विश्लेषण करके आपका कोड क्या समझ सकता है expression?

// `expression.NodeType` returns NodeType.Lambda.
// `expression.Type` returns Func<int, int, int>.
// `expression.ReturnType` returns Int32.

var body = expression.Body;
// `body.NodeType` returns ExpressionType.Add.
// `body.Type` returns System.Int32.

var parameters = expression.Parameters;
// `parameters.Count` returns 2.

var firstParam = parameters[0];
// `firstParam.Name` returns "a".
// `firstParam.Type` returns System.Int32.

var secondParam = parameters[1].
// `secondParam.Name` returns "b".
// `secondParam.Type` returns System.Int32.

यहाँ हम देखते हैं कि एक अभिव्यक्ति से हमें बहुत सी जानकारी मिल सकती है।

लेकिन हमें इसकी आवश्यकता क्यों होगी?

आपने सीखा है कि एक अभिव्यक्ति ट्री एक डेटा संरचना है जो निष्पादन योग्य कोड का प्रतिनिधित्व करता है। लेकिन अभी तक हमने केंद्रीय प्रश्न का उत्तर नहीं दिया है कि कोई ऐसा रूपांतरण क्यों करना चाहेगा। यह सवाल हमने इस पोस्ट की शुरुआत में पूछा है, और अब इसका जवाब देने का समय आ गया है।

LINQ to SQL क्वेरी को आपके C # प्रोग्राम के अंदर निष्पादित नहीं किया जाता है। इसके बजाय, यह SQL में अनुवादित होता है, एक तार के पार भेजा जाता है, और एक डेटाबेस सर्वर पर निष्पादित होता है। दूसरे शब्दों में, निम्नलिखित कोड को वास्तव में आपके प्रोग्राम के अंदर निष्पादित नहीं किया जाता है:
var query = from c in db.Customers where c.City == "Nantes" select new { c.City, c.CompanyName };

इसे पहले निम्न एसक्यूएल स्टेटमेंट में अनुवादित किया जाता है और फिर एक सर्वर पर निष्पादित किया जाता है:
SELECT [t0].[City], [t0].[CompanyName] FROM [dbo].[Customers] AS [t0] WHERE [t0].[City] = @p0

क्वेरी एक्सप्रेशन में पाए गए कोड को एसक्यूएल क्वैरी में अनुवादित किया जाना है जिसे एक स्ट्रिंग के रूप में दूसरी प्रक्रिया में भेजा जा सकता है। इस स्थिति में प्रक्रिया SQL सर्वर डेटाबेस होने के लिए होता है। यह स्पष्ट रूप से डेटा संरचना जैसे एसक्यूएल में एसक्यूएल में कच्चे आईएल या निष्पादन योग्य कोड का अनुवाद करने की तुलना में डेटा संरचना का अनुवाद करने के लिए बहुत आसान होने जा रहा है। समस्या की कठिनाई को कुछ हद तक अतिरंजित करने के लिए, बस ज़ीरो की एक श्रृंखला और एसक्यूएल में अनुवाद करने की कोशिश करें!

जब आपकी क्वेरी अभिव्यक्ति को SQL में अनुवाद करने का समय होता है, तो आपकी क्वेरी का प्रतिनिधित्व करने वाला एक्सप्रेशन ट्री अलग हो जाता है और इसका विश्लेषण किया जाता है, जैसे कि हमने पिछले भाग में अपने साधारण लैम्ब्डा एक्सप्रेशन ट्री को अलग किया था। दी, SQL अभिव्यक्ति ट्री को LINQ पार्स करने के लिए एल्गोरिथ्म बहुत अधिक परिष्कृत है जो हमने उपयोग किया था, लेकिन सिद्धांत समान है। एक बार जब उसने अभिव्यक्ति के पेड़ के हिस्सों का विश्लेषण किया है, तो LINQ उन्हें खत्म कर देता है और एसक्यूएल स्टेटमेंट लिखने का सबसे अच्छा तरीका तय करता है जो अनुरोधित डेटा को वापस कर देगा।

अभिव्यक्ति के पेड़ों को कोड के रूप में बदलने का कार्य करने के लिए बनाया गया था जैसे कि एक क्वेरी अभिव्यक्ति को एक स्ट्रिंग में जो किसी अन्य प्रक्रिया को पारित किया जा सकता है और वहां निष्पादित किया जा सकता है। यह इतना आसान है। यहां कोई महान रहस्य नहीं है, कोई जादू की छड़ी नहीं जिसे लहराया जाना है। एक बस कोड लेता है, इसे डेटा में परिवर्तित करता है, और फिर घटक को खोजने के लिए डेटा का विश्लेषण करता है जिसे एक स्ट्रिंग में अनुवादित किया जाएगा जिसे दूसरी प्रक्रिया में पारित किया जा सकता है।

क्योंकि इस तरह के सार डेटा संरचना में संकलित कंपाइलर के लिए क्वेरी आती है, कंपाइलर इसे किसी भी तरह से व्याख्या करने के लिए स्वतंत्र है जो वह चाहता है। यह किसी विशेष क्रम में या किसी विशेष तरीके से क्वेरी को निष्पादित करने के लिए मजबूर नहीं है। इसके बजाय, यह अभिव्यक्ति के पेड़ का विश्लेषण कर सकता है, खोज सकता है कि आप क्या चाहते हैं, और फिर यह तय करें कि इसे कैसे करना है। कम से कम सिद्धांत में, किसी भी संख्या में कारकों पर विचार करने की स्वतंत्रता है, जैसे कि वर्तमान नेटवर्क ट्रैफ़िक, डेटाबेस पर लोड, वर्तमान परिणाम इसे उपलब्ध है, आदि। LINQ to SQL में व्यवहार इन सभी कारकों पर विचार नहीं करता है , लेकिन यह सिद्धांत रूप में बहुत अधिक करने के लिए स्वतंत्र है कि वह क्या चाहता है। इसके अलावा, कोई भी इस अभिव्यक्ति ट्री को आपके द्वारा लिखे गए कुछ कस्टम कोड में बदल सकता है जो इसका विश्लेषण कर सकता है और इसे LINQ से SQL में निर्मित होने वाली चीज़ों से बहुत अलग में अनुवाद कर सकता है।

एक बार फिर, हम देखते हैं कि अभिव्यक्ति के पेड़ हमें प्रतिनिधित्व (व्यक्त?) करने की अनुमति देते हैं जो हम करना चाहते हैं। और हम ऐसे अनुवादकों का उपयोग करते हैं जो यह तय करते हैं कि हमारे भाव कैसे उपयोग किए जा रहे हैं।


2
बेहतर जवाबों में से एक है।
जॉनी

4
शानदार जवाब। इस शानदार विवरण में जोड़ने के लिए एक छोटा सा पहलू है - अभिव्यक्ति पेड़ों का एक और उपयोग यह है कि आप रन टाइम पर मक्खी पर अभिव्यक्ति के पेड़ को संशोधित कर सकते हैं क्योंकि आप इसे निष्पादित करने के लिए खिलाने से पहले फिट देख सकते हैं जो कई बार बेहद उपयोगी होता है।
यान डी

41

एक अभिव्यक्ति ट्री, निष्पादन योग्य कोड को डेटा में अनुवाद करने के लिए एक तंत्र है। एक अभिव्यक्ति पेड़ का उपयोग करके, आप एक डेटा संरचना का उत्पादन कर सकते हैं जो आपके कार्यक्रम का प्रतिनिधित्व करता है।

C # में, आप Expression<T>क्लास का उपयोग करके लैम्बडा एक्सप्रेशन द्वारा निर्मित अभिव्यक्ति ट्री के साथ काम कर सकते हैं ।


एक पारंपरिक कार्यक्रम में, आप इस तरह कोड लिखते हैं:

double hypotenuse = Math.Sqrt(a*a + b*b);

यह कोड संकलक को असाइनमेंट जनरेट करने का कारण बनता है, और यही वह है। ज्यादातर मामलों में, आप सभी की परवाह करते हैं।

पारंपरिक कोड के साथ, आपका एप्लिकेशन पूर्वव्यापी रूप से वापस नहीं जा सकता है और hypotenuseयह निर्धारित करने के लिए देख सकता है कि यह Math.Sqrt()कॉल करके प्रदर्शन किया गया था ; यह जानकारी शामिल नहीं है।

अब, निम्न की तरह एक लंबोदर अभिव्यक्ति पर विचार करें:

Func<int, int, double> hypotenuse = (a, b) => Math.Sqrt(a*a + b*b);

यह पहले की तुलना में थोड़ा अलग है। अब hypotenuseवास्तव में निष्पादन योग्य कोड के एक ब्लॉक का संदर्भ है । अगर तुम बुलाओ

hypotenuse(3, 4);

आपको मूल्य 5वापस मिल जाएगा ।

हम निष्पादन योग्य कोड के ब्लॉक का पता लगाने के लिए अभिव्यक्ति पेड़ों का उपयोग कर सकते हैं जो उत्पादन किया गया था। इसके बजाय यह प्रयास करें:

Expression<Func<int, int, int>> addTwoNumbersExpression = (x, y) => x + y;
BinaryExpression body = (BinaryExpression) addTwoNumbersExpression.Body;
Console.WriteLine(body);

यह उत्पादन करता है:

(x + y)

अभिव्यक्ति के पेड़ों के साथ अधिक उन्नत तकनीक और जोड़तोड़ संभव है।


7
ठीक है, मैं तुम्हारे साथ था अंत को झुकाओ, लेकिन मुझे अभी भी वास्तव में नहीं मिला कि यह एक बड़ी बात क्यों है। मैं आवेदनों की एक कठिन समय सोच रहा हूँ।

1
वह एक सरलीकृत उदाहरण का उपयोग कर रहा था; सच्ची शक्ति इस तथ्य में निहित है कि आपका कोड जो अभिव्यक्ति ट्री की खोज करता है, उसे व्याख्या करने और अभिव्यक्ति के अर्थ अर्थ को लागू करने के लिए भी जिम्मेदार बनाया जा सकता है।
पियरेटेन

2
हां, यह उत्तर बेहतर होता अगर वह / वह समझाता कि क्यों (x + y) वास्तव में हमारे लिए उपयोगी था। हम (x + y) क्यों अन्वेषण करना चाहते हैं और हम यह कैसे करते हैं?
पॉल मैथ्यूज

आपको इसका पता लगाने की ज़रूरत नहीं है, आप इसे केवल यह देखने के लिए करते हैं कि आपकी क्वेरी क्या है और उस मामले में किसी अन्य भाषा में एसक्यूएल के लिए अनुवाद किया जाएगा
stanimirsp

15

अभिव्यक्ति के पेड़ एक अभिव्यक्ति की एक स्मृति में प्रतिनिधित्व कर रहे हैं, जैसे एक अंकगणितीय या बूलियन अभिव्यक्ति। उदाहरण के लिए, अंकगणितीय अभिव्यक्ति पर विचार करें

a + b*2

चूँकि * के पास + की तुलना में एक उच्च संचालक पूर्वता है, इसलिए अभिव्यक्ति वृक्ष इस तरह बनाया गया है:

    [+]
  /    \
 a     [*]
      /   \
     b     2

इस वृक्ष के होने से, इसका मूल्यांकन a और b के किसी भी मान के लिए किया जा सकता है। इसके अतिरिक्त, आप इसे अन्य अभिव्यक्ति पेड़ों में बदल सकते हैं, उदाहरण के लिए अभिव्यक्ति को प्राप्त करने के लिए।

जब आप एक अभिव्यक्ति ट्री को लागू करते हैं, तो मैं एक बेस क्लास एक्सप्रेशन बनाने का सुझाव दूंगाउससे व्युत्पन्न, बाइनरी एक्सप्रेशन का उपयोग सभी बाइनरी एक्सप्रेशन जैसे + और * के लिए किया जाएगा। तब आप वैरिएबलरेंसप्रेशन एक्सप्रेशन को रेफरेंस वैरिएबल (जैसे कि ए और बी), और एक अन्य क्लास कॉन्स्टेंट एक्सप्रेशन (उदाहरण से 2 के लिए) पेश कर सकते हैं।

अभिव्यक्ति का पेड़ एक इनपुट पार्स करने के परिणाम के रूप में निर्मित कई मामलों में है (उपयोगकर्ता से सीधे, या फ़ाइल से)। अभिव्यक्ति ट्री के मूल्यांकन के लिए, मैं विज़िटर पैटर्न का उपयोग करने का सुझाव दूंगा


15

संक्षिप्त उत्तर: एक ही तरह की LINQ क्वेरी लिखना और किसी भी डेटा स्रोत पर इंगित करने में सक्षम होना अच्छा है। आपके पास इसके बिना "भाषा एकीकृत" क्वेरी नहीं हो सकती है।

लंबे उत्तर: जैसा कि आप शायद जानते हैं, जब आप स्रोत कोड संकलित करते हैं, तो आप इसे एक भाषा से दूसरी भाषा में बदल रहे हैं। आमतौर पर एक उच्च स्तर की भाषा (C #) से निम्न लीवर पर (IL)।

मूल रूप से दो तरीके हैं जिनसे आप यह कर सकते हैं:

  1. आप खोजने और बदलने का उपयोग करके कोड का अनुवाद कर सकते हैं
  2. आप कोड को पार्स करते हैं और पार्स ट्री प्राप्त करते हैं।

बाद के सभी कार्यक्रमों को हम 'कंपाइलर' के रूप में जानते हैं।

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

अब, LINQ में SQL को एक्सप्रेशन ट्री को SQL कमांड में बदल दिया जाता है और फिर वायर को डेटाबेस सर्वर पर भेजा जाता है। जहां तक ​​मुझे पता है कि कोड का अनुवाद करते समय वे वास्तव में कुछ भी नहीं करते हैं, लेकिन वे कर सकते थे । उदाहरण के लिए, क्वेरी प्रदाता नेटवर्क स्थितियों के आधार पर अलग SQL कोड बना सकता है।


6

IIUC, एक अभिव्यक्ति ट्री एक सार सिंटेक्स ट्री के समान है, लेकिन एक अभिव्यक्ति आमतौर पर एक एकल मूल्य को दर्शाता है, जबकि एक एएसटी एक संपूर्ण कार्यक्रम (कक्षाओं, पैकेज, फ़ंक्शन, स्टेटमेंट आदि के साथ) का प्रतिनिधित्व कर सकता है।

वैसे भी, अभिव्यक्ति के लिए (2 + 3) * 5, पेड़ है:

    *
   / \ 
  +   5
 / \
2   3

जड़ नोड पर मूल्य अर्थात अभिव्यक्ति के मूल्य को प्राप्त करने के लिए प्रत्येक नोड का पुनरावर्ती (नीचे-ऊपर) मूल्यांकन करें।

यदि आपकी अभिव्यक्ति भाषा इसकी अनुमति देती है, तो आप निश्चित रूप से एकरी (नकार) या त्रिशूल (यदि-तब-तब) ऑपरेटर भी कर सकते हैं, और फ़ंक्शंस (n-ary, यानी किसी भी संख्या में)।

प्रकारों का मूल्यांकन और प्रकार का नियंत्रण समान वृक्षों पर किया जाता है।


5

डीएलआर
अभिव्यक्ति पेड़ गतिशील भाषा रनटाइम (डीएलआर) का समर्थन करने के लिए सी # के अतिरिक्त हैं। DLR वह भी है जो हमें वैरिएबल घोषित करने की "विधि" देने के लिए जिम्मेदार है। ( var objA = new Tree();)

डीएलआर पर अधिक

अनिवार्य रूप से, Microsoft गतिशील भाषाओं के लिए CLR खोलना चाहता था, जैसे कि LISP, SmallTalk, जावास्क्रिप्ट, आदि। ऐसा करने के लिए, उन्हें मक्खी पर अभिव्यक्तियों का पार्स और मूल्यांकन करने में सक्षम होना चाहिए। डीएलआर के बारे में आने से पहले यह संभव नहीं था।

मेरे पहले वाक्य पर वापस, अभिव्यक्ति वृक्ष C # के अतिरिक्त हैं जो DLR का उपयोग करने की क्षमता को खोलता है। इससे पहले, C # बहुत अधिक स्थिर भाषा थी - सभी चर प्रकारों को एक विशिष्ट प्रकार के रूप में घोषित किया जाना था और सभी कोड को संकलन समय पर लिखा जाना था।

डेटा
एक्सप्रेशन पेड़ों के साथ इसका उपयोग करने से बाढ़ के द्वार गतिशील कोड में बदल जाते हैं।

उदाहरण के लिए, मान लें कि आप एक अचल संपत्ति साइट बना रहे हैं। डिज़ाइन चरण के दौरान, आप उन सभी फ़िल्टर को जानते हैं जिन्हें आप लागू कर सकते हैं। इस कोड को लागू करने के लिए, आपके पास दो विकल्प हैं: आप एक लूप लिख सकते हैं जो प्रत्येक डेटा बिंदु की तुलना अगर-चैक की श्रृंखला से करता है; या आप एक गतिशील भाषा (एसक्यूएल) में एक क्वेरी बनाने की कोशिश कर सकते हैं और उस प्रोग्राम को पास कर सकते हैं जो आपके लिए खोज (डेटाबेस) कर सकता है।

अभिव्यक्ति पेड़ों के साथ, अब आप अपने कार्यक्रम में कोड को बदल सकते हैं - मक्खी पर - और खोज निष्पादित करें। विशेष रूप से, आप LINQ के माध्यम से ऐसा कर सकते हैं।

(और देखें: MSDN: डायनेमिक क्वेरी बनाने के लिए अभिव्यक्ति पेड़ों का उपयोग कैसे करें )।

डेटा से परे
अभिव्यक्ति पेड़ों के लिए प्राथमिक उपयोग डेटा के प्रबंधन के लिए हैं। हालांकि, उनका उपयोग गतिशील रूप से उत्पन्न कोड के लिए भी किया जा सकता है। इसलिए, यदि आप एक फ़ंक्शन चाहते हैं जिसे गतिशील रूप से परिभाषित किया गया है (ala जावास्क्रिप्ट), तो आप एक अभिव्यक्ति ट्री बना सकते हैं, इसे संकलित कर सकते हैं और परिणामों का मूल्यांकन कर सकते हैं।

मैं थोड़ा और गहराई में जाऊंगा, लेकिन यह साइट बहुत बेहतर काम करती है:

एक संकलक के रूप में अभिव्यक्ति पेड़

सूचीबद्ध उदाहरणों में वैरिएबल प्रकारों के लिए जेनेरिक ऑपरेटर्स बनाना, हैंड-रोलिंग लैम्ब्डा एक्सप्रेशंस, हाई परफॉरमेंस उथला क्लोनिंग, और डायनामिकली रीडिंग / राइटिंग प्रॉपर्टीज़ को एक ऑब्जेक्ट से दूसरी में शामिल करना शामिल है।

सारांश
अभिव्यक्ति पेड़ उस कोड का प्रतिनिधित्व करते हैं जो रनटाइम पर संकलित और मूल्यांकन किया जाता है। वे गतिशील प्रकारों के लिए अनुमति देते हैं, जो डेटा हेरफेर और गतिशील प्रोग्रामिंग के लिए उपयोगी है।


हाँ, मुझे पता है कि मुझे खेल में देर हो गई है, लेकिन मैं इस उत्तर को खुद को समझने के तरीके के रूप में लिखना चाहता था। (यह प्रश्न मेरी इंटरनेट खोज में बहुत ऊपर आया।)
रिचर्ड

अच्छी नौकरी। यह एक अच्छा जवाब है।
रिच ब्रायंट

5
"Var" कीवर्ड का DLR से कोई लेना-देना नहीं है। आप इसे "गतिशील" के साथ भ्रमित कर रहे हैं।
यारक

यह यहाँ पर एक अच्छा, छोटा सा जवाब है, जो दिखाता है कि यारिक सही है। हालांकि, बाकी जवाब के लिए धन्यवाद। quora.com/…
जॉनी

1
यह सब गलत है। varएक संकलित समय-संश्लिष्ट चीनी है - इसका अभिव्यक्ति पेड़, DLR या रनटाइम से कोई लेना-देना नहीं है। var i = 0जैसा कि आपने लिखा है int i = 0, वैसे ही संकलित हो जाता है , इसलिए आप varउस प्रकार का प्रतिनिधित्व करने के लिए उपयोग नहीं कर सकते हैं जो संकलन-समय में ज्ञात नहीं है। अभिव्यक्ति के पेड़ "DLR का समर्थन करने के लिए एक अतिरिक्त" नहीं हैं, उन्हें LINQ की अनुमति देने के लिए .NET 3.5 में पेश किया गया है। दूसरी ओर DLR को डायनेमिक भाषाओं (जैसे IronRuby) और dynamicकीवर्ड को अनुमति देने के लिए .NET 4.0 में पेश किया गया है । अभिव्यक्ति के पेड़ वास्तव में डीएलआर द्वारा इंटरोप प्रदान करने के लिए उपयोग किए जाते हैं, यह दूसरा तरीका नहीं है।
गेर

-3

क्या अभिव्यक्ति का पेड़ जिसे आप संदर्भित कर रहे हैं अभिव्यक्ति अभिव्यक्ति का पेड़ है?

यदि हाँ तो यह पेड़ पार्सर द्वारा निर्मित है। पार्सर ने कार्यक्रम से टोकन की पहचान करने के लिए लेक्सर / टोकनराइज़र का उपयोग किया। पार्सर टोकन से बाइनरी ट्री का निर्माण करता है।

यहां विस्तृत विवरण दिया गया है


खैर, यह सच है कि एक अभिव्यक्ति ट्री कि ओपी समान कार्य करता है और एक पार्स ट्री के समान अंतर्निहित अवधारणा के साथ, यह गतिशील रूप से कोड के साथ रन-टाइम पर किया जाता है, हालांकि ध्यान दें कि वह रोजलिन कंपाइलर की लाइन का परिचय देता है। यदि पूरी तरह से हटाया नहीं गया तो दोनों के बीच विभाजन वास्तव में धुंधला हो गया।
योएल हैल्ब
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.