प्रारंभिक और देर से बाध्यकारी


83

जब C # में जल्दी / देर से बाध्यकारी होता है, तो मैं अपना सिर घुमाने की कोशिश कर रहा हूं।

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

प्रतिबिंब का उपयोग करते हुए कॉलिंग विधियां देर से बाध्यकारी का एक उदाहरण है। हम संकलक के विपरीत इसे प्राप्त करने के लिए कोड लिखते हैं। (जैसे COM घटकों को कॉल करना।)

विकल्प स्ट्रिक्ट बंद होने पर VB.NET निहित देर बंधन का समर्थन करता है। ऑब्जेक्ट तब देर से बँधा होता है जब उसे एक प्रकार के ऑब्जेक्ट के रूप में घोषित एक चर को सौंपा जाता है। VB कंपाइलर कोड को निष्पादन के समय सही विधि से बाँधने और अमान्य कॉल को पकड़ने के लिए सम्मिलित करता है। C # इस सुविधा का समर्थन नहीं करता है।

क्या मैं सही दिशा में जा रहा हूं?

एक प्रतिनिधि संदर्भ के माध्यम से प्रतिनिधियों को कॉल करने और एक विधि को कॉल करने के बारे में क्या? क्या यह जल्दी या देर से बाध्यकारी है?

जवाबों:


103

जब तक आप रिफ्लेक्शन इंटरफ़ेस के माध्यम से नहीं जाते हैं, तब तक सब कुछ C # में बाध्य है।

प्रारंभिक बाउंड का मतलब है कि लक्ष्य विधि संकलन समय पर पाई जाती है, और कोड बनाया जाता है जो इसे कॉल करेगा। चाहे उसका वर्चुअल हो या न हो (मतलब कॉल टाइम पर उसे ढूंढना अप्रासंगिक है)। यदि विधि मौजूद नहीं है तो संकलक कोड संकलित करने में विफल होगा।

लेट बाउंड का मतलब रन टाइम के दौरान टारगेट मेथड को देखा जाता है। अक्सर इसे देखने के लिए विधि के पाठ नाम का उपयोग किया जाता है। यदि विधि नहीं है, तो धमाका करें। प्रोग्राम क्रैश हो जाएगा या रन टाइम में कुछ अपवाद हैंडलिंग स्कीम में चला जाएगा।

अधिकांश स्क्रिप्ट भाषाएं देर से बाध्यकारी का उपयोग करती हैं, और संकलित भाषा शुरुआती बाध्यकारी का उपयोग करती हैं।

सी # (संस्करण 4 से पहले) देर से बाँध नहीं करता है; हालांकि वे इसे करने के लिए प्रतिबिंब एपीआई का उपयोग कर सकते हैं। वह एपीआई कोड को संकलित करता है जो रन टाइम पर असेंबली के माध्यम से खुदाई करके फ़ंक्शन नामों को देखता है। विकल्प स्ट्रिक्ट बंद होने पर VB देर से बाँध सकता है।

आमतौर पर बाइंडिंग के प्रदर्शन पर असर पड़ता है। क्योंकि देर से बाइंडिंग को रनटाइम पर लुकअप की आवश्यकता होती है, आमतौर पर इसका मतलब है कि विधि कॉल शुरुआती बाध्य विधि कॉल की तुलना में धीमी है।


एक सामान्य फ़ंक्शन के लिए, कंपाइलर मेमोरी में इसके संख्यात्मक स्थान का पता लगा सकता है। तब यह जब फ़ंक्शन कहा जाता है, तो यह इस पते पर फ़ंक्शन को कॉल करने के लिए एक निर्देश उत्पन्न कर सकता है।

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

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

जल्दी बँधा हुआ

  • कंपाइलर बाहर काम कर सकता है जहां संकलित फ़ंक्शन संकलन समय पर होगा।
  • कंपाइलर जल्दी गारंटी दे सकता है (किसी भी प्रोग्राम कोड चलने से पहले) कि फ़ंक्शन मौजूद होगा और रनटाइम पर कॉल करने योग्य होगा।
  • कंपाइलर गारंटी देता है कि फ़ंक्शन सही संख्या में तर्क लेता है और यह कि वे सही प्रकार के हैं। यह भी जांचता है कि रिटर्न वैल्यू सही प्रकार की है।

देर बाध्यकारी

  • यह देखने में अधिक समय लगेगा क्योंकि इसकी एक साधारण ऑफसेट गणना नहीं होती है, आमतौर पर पाठ की तुलना की जाती है।
  • लक्ष्य फ़ंक्शन मौजूद नहीं हो सकता है।
  • हो सकता है कि टार्गेट फंक्शन उसके पास गए तर्कों को स्वीकार न करे, और गलत प्रकार का रिटर्न वैल्यू हो।
  • कुछ कार्यान्वयन के साथ, लक्ष्य पद्धति वास्तव में रन-टाइम में बदल सकती है। इसलिए, लुकअप किसी भिन्न फ़ंक्शन को निष्पादित कर सकता है। मुझे लगता है कि यह रूबी भाषा में होता है, आप एक वस्तु पर एक नई विधि को परिभाषित कर सकते हैं, जबकि कार्यक्रम चल रहा है। लेट-बाइंडिंग फ़ंक्शन कॉल को मौजूदा बेस विधि को कॉल करने के बजाय एक विधि के लिए एक नया ओवरराइड कॉल करना शुरू करने की अनुमति देता है।

मुझे लगता है कि आपके कहने का मतलब "वीबी भाषा ही देर से बाँधती नहीं है ..."
माइकल मीडोज

वास्तव में, मैं VB का उपयोग नहीं करता ... इसलिए मुझे इसके बारे में बहुत कुछ पता नहीं है। मेरा मतलब सी # था, लेकिन ऐसा लग रहा है कि मैं खुद को दोहरा रहा था। मैं कल्पना करूँगा कि आप सही हैं, इसलिए मैं इसे ठीक करूँगा!
स्कॉट लैंगहम

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

1
" ऐसी वस्तु के लिए जिसमें कोई आभासी विधियां हों, कंपाइलर एक वी-टेबल उत्पन्न करेगा। " यह थोड़ा गलत है - "क्लास", "ऑब्जेक्ट" नहीं।
हल्दस-मेरुला

1
@IvanRuski मुझे ऐसा नहीं लगता। संकलन के समय, सभी तर्क टाइप होते हैं जो एक प्रतिनिधि स्वीकार करता है। इसलिए, संकलन समय पर (जो कि 'जल्दी' है) रनटाइम (जो कि 'देर' है) के बजाय, कंपाइलर गारंटी दे सकता है कि कॉल काम करेगा।
स्कॉट लैंगहम

18

सी # 3 जल्दी बाध्यकारी का उपयोग करता है।

C # 4 dynamicकीवर्ड के साथ देर से बाध्यकारी जोड़ता है । देखें क्रिस बरो के ब्लॉग प्रविष्टि जानकारी के लिए इस विषय पर।

आभासी बनाम गैर-आभासी तरीकों के लिए, यह एक अलग मुद्दा है। अगर मैं कॉल करता हूं string.ToString(), तो C # कोड वर्चुअल object.ToString()मेथड से बंध जाता है । ऑब्जेक्ट के प्रकार के आधार पर कॉलर का कोड नहीं बदलता है। बल्कि, फंक्शन पॉइंटर्स की तालिका के माध्यम से वर्चुअल तरीकों को बुलाया जाता है। ऑब्जेक्ट का एक उदाहरण ऑब्जेक्ट की तालिका को इंगित करता है जो इसे ToString()विधि बताता है। स्ट्रिंग की एक आवृत्ति में यह वर्चुअल मेथड टेबल है जो इसे ToString()विधि बताता है। हाँ, यह बहुरूपता है। लेकिन यह देर से बाध्यकारी नहीं है।


1
मैं इस स्पष्टीकरण से पूरी तरह सहमत नहीं हूं। C # में इंस्टेंस विधि या फ़ील्ड को वर्चुअल साधनों के रूप में चिन्हित करने से व्युत्पन्न श्रृंखला में आधार प्रकार के कार्यान्वयन को ओवरराइड किया जा सकता है। आभासी विधियों के साथ, सीएलआर जानता है कि रन टाइम ऑब्जेक्ट उदाहरण के आधार पर रन टाइम पर कॉल करने की कौन सी विधि है। संभवतः, मैं आपके साथ सहमत होने वाला एकमात्र हिस्सा है, यह बहुरूपता का कार्यान्वयन है। फिर आप यह कहकर भ्रम पैदा करते हैं कि यह देर से बाध्यकारी नहीं है। यह देर से बाध्यकारी है क्योंकि सीएलआर केवल सही रन टाइम टाइप कार्यान्वयन को कॉल कर सकता है जब वह ऑब्जेक्ट उदाहरण के रन टाइम प्रकार को जानता है।
बजे जूलियस डेपुल्ला

6

ज्यादातर मामलों में शुरुआती बाध्यकारी वह है जो हम दैनिक आधार पर करते हैं। उदाहरण के लिए, यदि हमारे पास Employeeसंकलन समय पर एक कक्षा उपलब्ध है, तो हम बस उस वर्ग का उदाहरण बनाते हैं और किसी भी उदाहरण के सदस्यों को आमंत्रित करते हैं। यह जल्दी बाध्यकारी है।

//Early Binding
**Employee** employeeObject = new **Employee**();
employeeObject.CalculateSalary();

दूसरी ओर, यदि आपके पास संकलन के समय कक्षा का ज्ञान नहीं है, तो एक ही तरीका है कि प्रतिबिंब का उपयोग करके देर से बाँधें। मैं इन अवधारणाओं को समझाते हुए एक उत्कृष्ट वीडियो पर आया हूं - यहां लिंक है


3

इसकी बहुत पुरानी पोस्ट है, लेकिन इसमें और जानकारी जोड़ना चाहते हैं। लेट बाइंडिंग का उपयोग तब किया जाता है जब आप संकलन समय पर ऑब्जेक्ट को इंस्टेंट करना नहीं चाहते हैं। में C#आप का उपयोग Activatorक्रम में बाँध वस्तु कॉल करने के लिए।


3

अर्ली बाइंडिंग

नाम ही वर्णन करता है कि संकलक को पता है कि यह किस प्रकार की वस्तु है, इसमें सभी तरीके और गुण हैं। जैसे ही आपने ऑब्जेक्ट घोषित किया, .NET Intellisense डॉट बटन पर क्लिक करने पर इसके तरीकों और गुणों को पॉप्युलेट करेगा।

सामान्य उदाहरण:

ComboBox cboItems;

सूचीबॉक्स lstItems; उपरोक्त उदाहरणों में, यदि हम कॉबीम टाइप करते हैं और उसके बाद एक डॉट लगाते हैं, तो यह कॉम्बो बॉक्स के सभी तरीकों, घटनाओं और गुणों को स्वचालित रूप से पॉप्युलेट करेगा, क्योंकि कंपाइलर पहले से ही जानते हैं कि यह एक कॉम्बोक्स है।

देर से बांधना

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

सामान्य उदाहरण:

वस्तु objItems;

objItems = CreateObject ("DLL या असेंबली नाम"); संकलन के समय में यहाँ, objItems का प्रकार निर्धारित नहीं किया गया है। हम एक dll का ऑब्जेक्ट बना रहे हैं और इसे objItems को असाइन कर रहे हैं, इसलिए सब कुछ रन टाइम पर निर्धारित किया जाता है।

अर्ली बाइंडिंग बनाम लेट बाइंडिंग

अब चित्र में आ रहे हैं â â

अर्ली बाइंडिंग में एप्लिकेशन तेजी से चलेगा, क्योंकि यहां कोई बॉक्सिंग या अनबॉक्सिंग नहीं की जाती है।

कोड को प्रारंभिक बाध्यकारी में लिखना आसान है, क्योंकि इंटेलीजेंस स्वचालित रूप से आबाद हो जाएगा

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

देर से बाध्यकारी सभी प्रकार के संस्करणों में समर्थन करेगा, क्योंकि सब कुछ रन समय पर तय किया गया है।

यदि लेट बाइंडिंग का उपयोग किया जाता है, तो भविष्य के संवर्द्धन में कोड का न्यूनतम प्रभाव।

शुरुआती बाध्यकारी में प्रदर्शन कोड होगा। दोनों में योग्यता और अवगुण हैं, यह परिदृश्य के आधार पर उपयुक्त बाध्यकारी चुनने के लिए डेवलपर निर्णय है।


2

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

http://www.youtube.com/watch?v=s0eIgl5iqqQ&list=PLAC325451207E3105&index=55&feature=plpp_video

http://www.youtube.com/playlist?list=PLAC325451207E3105


1

यह आलेख एक .net घटक के निर्माण के लिए एक मार्गदर्शिका है, इसे Vb6 प्रोजेक्ट में रनिंग में लेट बाइंडिंग का उपयोग करते हुए, इसे इवेंट्स अटैच करके कॉलबैक प्राप्त करें।

http://www.codeproject.com/KB/cs/csapivb6callback2.aspx

यह आलेख .NET घटक बनाने और VB6 प्रोजेक्ट में इसका उपयोग करने के लिए एक गाइड है। इस मुद्दे के बारे में कई नमूने हैं, इसलिए मैंने एक नया क्यों लिखा? मेरी विनम्र राय में, अन्य लेखों में, लापता भाग को रनटाइम पर अपनी घटना को संलग्न करना है। तो इस लेख में, हम एक .NET घटक का निर्माण करेंगे, इसे एक COM दृश्य घटक के रूप में चिह्नित करेंगे, इसे VB6 में रनटाइम पर उपयोग करें और इसकी घटनाओं के साथ संलग्न करें।

https://www.codeproject.com/Articles/37127/Internet-Explorer-Late-Binding-Automation

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

सबसे आम तरीका है shdocvw.dll (Microsoft वेब ब्राउज़र नियंत्रण) और Mshtml.dll (HTML पार्सिंग और रेंडरिंग घटक), या Microsoft.Mshtml.dll जो वास्तव में Mshtml.dll के लिए एक .NET आवरण है। आप Internet Explorer - ब्राउज़र के बारे में अधिक जानकारी यहाँ से प्राप्त कर सकते हैं।

यदि आप उपरोक्त विधि और DLL चुनते हैं, तो चलिए कुछ समस्याओं को देखते हैं जिनसे आपको निपटना पड़ सकता है:

आपको इन DLL को वितरित करना होगा क्योंकि आपकी परियोजना इन DLL पर निर्भर होगी, और यह एक गंभीर समस्या है यदि आप उन्हें सही तरीके से तैनात नहीं कर सकते हैं। बस shdocvw और mshtml.dll वितरण समस्याओं के बारे में कुछ Googling करते हैं, और आप देखेंगे कि मैं किस बारे में बात कर रहा हूं। आपको 8 MB Microsoft.mshtml.dll परिनियोजित करना होगा क्योंकि यह DLL .NET फ्रेमवर्क का हिस्सा नहीं है। इस मामले में, हमें जो करने की आवश्यकता है वह एक देर से बाध्यकारी तकनीक का उपयोग करना है। उपर्युक्त DLL के लिए हमारे अपने रैपर लिखना। और निश्चित रूप से, हम ऐसा करेंगे क्योंकि यह इन DLL का उपयोग करने से अधिक उपयोगी है। उदाहरण के लिए, हमें यह जांचने की आवश्यकता नहीं होगी कि दस्तावेज़ डाउनलोड ऑपरेशन पूरा हो गया है क्योंकि IEHelper हमारे लिए ऐसा करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.