2012-06-22 11 views
8

मैं कल्पना कर सकते हैं इस Reflection.Emit उपयोग कर सकते हैं,रनटाइम पर एक मौजूदा कक्षा में कोई विधि जोड़ना संभव है? क्यों या क्यों नहीं?

लेकिन a similar question on SO केवल एक मौजूदा वर्ग अद्यतन करने के लिए कैसे गतिशील रूप से एक वर्ग/विधि बनाने का तरीका, नहीं जवाब।

इसी तरह से, क्या रनटाइम पर विधियों/कक्षाओं को हटाना संभव है? यदि ऐसा है, तो मुझे लगता है कि कोई भी कक्षा को हटा सकता है, और इसे अपने पुराने तरीकों के साथ-साथ नया जोड़ सकता है।

अग्रिम धन्यवाद।

पीएस मेरे पास इसका इरादा नहीं है, यह केवल जिज्ञासा का मामला है।

+4

यह एक आदर्श उदाहरण है कि क्यों SO प्रश्नों में प्रति पोस्ट केवल एक प्रश्न होना चाहिए। मार्क और हेनक ने आपके द्वारा पूछे गए एक अलग प्रश्न का उत्तर दिया, और दोनों अच्छे, सही उत्तर हैं। आप ** सही ** एक के रूप में कौन सा चुनते हैं और स्वीकार करते हैं? इस स्थिति से बचने के लिए कृपया प्रति पोस्ट ** एकल ** प्रश्न पर सीमित रहें, जहां उत्तरदाताओं में से एक को पुरस्कृत किया जाता है और दूसरा नहीं करता है, भले ही दोनों उत्तर अच्छे, सही और आपके प्रश्न का उत्तर दें। –

+0

ठीक है। मैं भविष्य में याद रखने की कोशिश करूंगा। विधियों/वस्तुओं के बजाय प्रश्नों के लिए एकल उद्देश्य सिद्धांत।अब जब कार्य किया गया है, मुझे शायद इसे बदलना नहीं चाहिए। – user420667

उत्तर

26

नियमित सी #/.NET में, उत्तर एक साधारण "नहीं" है। आप जितना अधिक कर सकते हैं वह DynamicMethod लिख सकता है जो उस प्रकार की विधि (निजी फ़ील्ड्स तक पहुंच) की तरह व्यवहार कर सकता है, लेकिन यह कभी भी एपीआई पर नहीं होगा - आप बस एक प्रतिनिधि के साथ समाप्त हो जाते हैं।

यदि आप dynamic का उपयोग करते हैं, तो आप जो कुछ भी चाहते हैं वह कर सकते हैं। संलग्न करके ExpandoObject के साथ को विधियों के स्थान पर को जोड़कर, लेकिन एक कस्टम गतिशील प्रकार पर आप अधिक कुछ भी कर सकते हैं - लेकिन यह केवल dynamic API का उपयोग करने वाले कॉलर्स को प्रभावित करता है। एक बुनियादी ExpandoObject उदाहरण के लिए:

dynamic obj = new ExpandoObject(); 
Func<int, int> func = x => 2*x; 
obj.Foo = func; 
int i = obj.Foo(123); // now you see it 
obj.Foo = null; // now you don't 

गुण और घटनाओं (नहीं विधि) के लिए, आप क्या क्रम में दिखाई देता है बदलने के लिए System.ComponentModel दृष्टिकोण का उपयोग कर सकते हैं, लेकिन यह केवल प्रभावों कॉल जो, System.ComponentModel के माध्यम से पहुँच जाते हैं जिसका अर्थ है मुख्य रूप से: यूआई डेटा बाध्यकारी। इस प्रकार DataTable छद्म गुणों के रूप में कॉलम का प्रतिनिधित्व करता है (इस समय के लिए "टाइप किए गए डेटासेट" के बारे में भूलना - यह उन के बिना काम करता है)।

पूर्णता के लिए, मुझे विस्तार विधियों का भी उल्लेख करना चाहिए। वे एक कंपाइलर चाल हैं, रनटाइम चाल नहीं - लेकिन kinda आपको "एड" के छोटे मानों के लिए मौजूदा प्रकार के तरीकों को जोड़ने की अनुमति देता है।

एक अंतिम चाल, आमतौर पर ओआरएम आदि द्वारा उपयोग की जाती है - गतिशील रूप से उपclass प्रकार है, और सबक्लास में अतिरिक्त कार्यक्षमता प्रदान करता है। उदाहरण के लिए, उन्हें अवरुद्ध करने के लिए गुणों को ओवरराइड करना (आलसी लोडिंग, आदि)।

+0

हाहा, "जोड़ने के छोटे मूल्यों के लिए"। मुझे लगता है कि इसका मतलब स्थिर तरीकों के लिए है :- पी। – user420667

+0

@ user420667 नहीं, असल में मेरा मतलब है "वे वास्तव में इस प्रकार के तरीके नहीं हैं"। –

+0

महान प्रतिक्रिया। हालांकि क्यों के बारे में कोई विचार? क्या यह कुछ प्रकार के विकास प्रिंसिपल को तोड़ देगा/इसे लागू करने में कठोर होगा? – user420667

3

रनटाइम पर विधियों/कक्षाओं को हटाना संभव है?

मान लीजिए कि यह संभव था। उन तरीकों के लिए कॉल विफल हो जाएंगे और अपरिभाषित (लेकिन आमतौर पर विनाशकारी) व्यवहार का उत्पादन करेंगे।

तो मुझे यकीन है कि यह संभव नहीं है।

+0

आमतौर पर अनिर्धारित * मतलब * विनाशकारी! ;) –

+0

कैच (अपरिभाषित मोड/अपरिभाषित क्लास अपवाद)? :-P – user420667

+3

@ user420667 'MissingMethodException' और 'TypeLoadException' है। वे तब हो सकते हैं जब आप एक असेंबली के एक संस्करण के खिलाफ अपना कोड बनाते हैं, लेकिन फिर इसे किसी अन्य संस्करण के विरुद्ध चलाएं, जिसमें विधि या प्रकार गुम है। – svick

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