2010-12-18 20 views
10

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

उत्तर

9

विस्तार के तरीकों के लिए एक स्थिर विधि के पहले पैरामीटर के सामने this कीवर्ड डालकर निर्दिष्ट कर रहे हैं जब संकलक उस विशेषता को देखता है, तो यह एक्सटेंशन विधि कॉल को उचित स्थिर विधि कॉल में अनुवाद करना जानता है, उदाहरण को पहले पैरामीटर के रूप में पास करना।

चूंकि कॉल केवल सामान्य स्थैतिक विधि कॉल हैं, इसलिए encapsulation तोड़ने का कोई मौका नहीं है; विधियों, सभी स्थिर तरीकों की तरह, केवल विस्तारित प्रकार के सार्वजनिक इंटरफेस तक पहुंच है।

+0

+1 अच्छा बिंदु :) –

16

वे "हुक अप" नहीं करते हैं।

विसाउल स्टूडियो आईडीई सिर्फ इंटेलिजेंस सूचियों में दिखाकर ऐसा लगता है।

कंपाइलर सही पैरामीटर के साथ सही विधि कॉल करने के लिए संदर्भों से निपटने के लिए "जानता है"।

यह केवल syntactic sugar है - विधियां एक अलग स्थैतिक वर्ग पर बस स्थिर तरीके हैं। this संशोधक का उपयोग करके कंपाइलर को ExtensionAttribute कक्षा में एक्सटेंशन विधि के रूप में चिह्नित करने के लिए "पता" करने देता है।

के बाद से विस्तार तरीकों करना वास्तव में परिवर्तन वर्ग और केवल उस पर सार्वजनिक सदस्यों तक पहुँच सकते हैं, कैप्सूलीकरण बनाए रखा है नहीं।

MSDN से:

एक्सटेंशन तरीकों स्थिर विधि का एक विशेष प्रकार का है, लेकिन वे कहा जाता है के रूप में यदि वे विस्तारित प्रकार पर उदाहरण के तरीकों थे।

(जोर मेरा)

4

एक्सटेंशन तरीके हैं बस वाक्यात्मक चीनी, वे सिर्फ स्थिर तरीके हैं। आप केवल सामान्य स्थैतिक तरीकों की तरह, सार्वजनिक क्षेत्रों या गुणों तक पहुंचने में सक्षम हैं।

[Extension] 
public static void SomeExtension(string s) 
{ 
    ... 
} 

:

public static void SomeExtension(this string s) 
{ 
    ... 
} 

System.Runtime.CompilerServices.ExtensionAttribute साथ विधि सजाने के लिए बस वाक्यात्मक चीनी है:

2

मुख्य घटक यह है कि कक्षा का एक उदाहरण विधि मूलभूत विधि से मूल रूप से अलग नहीं है। एक छोटी सी जानकारी के साथ, उनके पास एक छिपी हुई तर्क है।

public static int IndexOf(string thisRef, char value) { 
    // etc... 
} 

thisRef तर्क है क्या स्ट्रिंग संदर्भ की आपूर्ति जब भी आप अपने कोड में इस का उपयोग करें या एक सदस्य का उपयोग: उदाहरण के लिए, String.IndexOf (चार) विधि वास्तव में CLR करने के लिए इस तरह दिखता है कक्षा का जैसा कि आप देख सकते हैं, यह एक बहुत एक विस्तार विधि से एक उदाहरण विधि से छोटा कदम है।सुविधा का समर्थन करने के लिए सीएलआर में कोई बदलाव आवश्यक नहीं था।

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

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

इसका एक और स्वचालित परिणाम यह है कि एक विस्तार विधि वर्चुअल नहीं हो सकती है।

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