2012-04-04 6 views
9
public static class MyClass 
{ 
    public static void Print<T>(this T theObject) 
    { 
     Console.WriteLine("The print output is " + theObject.ToString()); 
    } 
} 

दिए गए वर्ग में मैंने this कीवर्ड के माध्यम से विस्तार के प्रकार के रूप में एक सामान्य निर्दिष्ट किया है। ऐसा होने के कारण मैंने संकलन समय तक इस प्रकार की परिभाषा में देरी कर दी है, इंटेलिजेंस (और कुछ और शामिल) कैसे जानता है कि मैं किस प्रकार का विस्तार कर रहा हूं? क्या सी # बस शीर्ष स्तर System.Object पर डिफ़ॉल्ट है?सामान्य विस्तार विधि बनाते समय हम क्या विस्तार कर रहे हैं?

+2

LINQ के साथ इसका क्या संबंध है? – BoltClock

+0

@ बोल्टक्लो'साइनिकर्न लिनक में पूरे धाराप्रवाह sytnax विस्तार विधियों पर आधारित है। –

+2

@RoyiNamir तथ्य यह है कि LINQ विस्तार विधियों पर आधारित है, LINQ से संबंधित सभी एक्सटेंशन विधियों को नहीं बनाता है। – Servy

उत्तर

1

ऐसा होने के कारण मैंने संकलन समय तक प्रकार की परिभाषा में देरी की है, इंटेलिजेंस (और कुछ और शामिल) कैसे पता चलता है कि मैं किस प्रकार का विस्तार कर रहा हूं? सी # बस शीर्ष स्तर सिस्टम के लिए डिफ़ॉल्ट है। ऑब्जेक्ट?

जो लोग कहते हैं कि यह System.Object पर एक एक्सटेंशन गलत है। एक के लिए, यह विधि बॉक्स मान प्रकार इनपुट नहीं होगी, लेकिन System.Object पर परिभाषित एक एक्सटेंशन विधि होगी।

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

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

static class Foo { 
    public static void M(this object obj) { } 
} 

एक स्थैतिक वर्ग में केवल एक स्थिर विधि है। आप इसे इस तरह कह सकते हैं:

Foo.M(obj); 

लेकिन यह एक उदाहरण विधि है जैसे हम इसे कॉल कर सकते हैं:

obj.M(); 

इस प्रकार, आप एक सामान्य विस्तार विधि है जब, एक मिनट के लिए बंद करो और इसके बारे में सोचो एक स्थिर कक्षा में एक स्थिर पद्धति के रूप में

static class Foo { 
    public static void M<T>(this T obj) { } 
} 

आप इस तरह यह कह सकते हैं:

object obj; 
Foo.M(obj); 

या आप इसे इस तरह से कॉल कर सकते हैं:

obj.M(); 

संकलक जो आप लिखने के लिए कोई फर्क नहीं है।

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

+0

+1 यह जानने के लिए उपयोगी जानकारी है। यह कैसे है कि चाल काम करता है? क्या हम मानते हैं कि यह वाक्य रचनात्मक चीनी है? दूसरे शब्दों में, क्या संकलक बस 'obj.M() '' foo.M (obj) 'के कॉल को रूपांतरित करता है? –

+1

हां, यह सिर्फ वाक्य रचनात्मक चीनी है। भाषा विनिर्देश के 7.6.5.2 देखें। विशेष रूप से, उस अनुभाग में "विधि कॉल को तब एक स्थिर विधि आमंत्रण के रूप में संसाधित किया जाता है" कथन दिया जाता है। – jason

+0

@ जेसन 95% सिटेटिक चीनी के बारे में जानकारी और 'हम क्या विस्तार कर रहे हैं' के बारे में 5% कृपया ** प्रमाण ** की आपूर्ति करें कि हम system.object का विस्तार नहीं कर रहे हैं। –

3

हां, यह System.Object है जब तक आप एक प्रकार की बाधा नहीं जोड़ते।

+1

@ रॉयनामिर: जेनेरिक ** पैरामीटर ** ('() प्रिंट करें) बाधाओं ('जहां टी: कुछ टाइप') नहीं हो सकता है। –

+0

@ जॉर्ज डकेट मेरा मतलब था कि आपको प्रकार जोड़ने की ज़रूरत नहीं है। टी –

+0

ऑब्जेक्ट पर विस्तार करना वही बात नहीं है जो सामान्य प्रकार के पैरामीटर के रूप में मान्य सभी प्रकारों पर विस्तारित है। यह 'ऑब्जेक्ट' पर विस्तार नहीं है। – jason

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