2009-03-14 15 views
20

में कक्षा में गतिशील रूप से फ़ील्ड कैसे जोड़ सकता हूं क्या Field (या FieldInfo, शायद यह वही है) को रनटाइम पर कक्षा में जोड़ने का कोई तरीका है?मैं सी #

+0

संभव डुप्लिकेट http://stackoverflow.com/questions/947241/how-do-i-create-dynamic-properties-in-c) – nawfal

उत्तर

24

आप रनटाइम पर कक्षा परिभाषा को बदल नहीं सकते हैं। हालांकि, आप एक नई कक्षा बना सकते हैं जो मूल वर्ग से प्राप्त होती है (यदि यह sealed नहीं है) और फ़ील्ड घोषित करता है। आप System.Reflection.Emit का उपयोग कर उपयुक्त आईएल कोड उत्सर्जित करके ऐसा कर सकते हैं।

6

नहीं, सी # monkey-patching की अनुमति नहीं देता है।

आप कोडोडॉम या प्रतिबिंब का उपयोग कर नए कक्षाएं उत्पन्न कर सकते हैं, लेकिन आप मौजूदा लोगों को संशोधित नहीं कर सकते हैं।

+1

इसे बंदर-पैचिंग कहा जाता है? वह शब्द कहां से आया? –

+0

कोई विचार नहीं है कि यह कहां से आता है, लेकिन मैंने विकिपीडिया प्रविष्टि के लिए एक लिंक जोड़ा है। –

+1

बंदर पैचिंग एक शब्द है जो रूबी से आता है। जैफ एटवुड ने कुछ साल पहले एक ब्लॉग पोस्ट में इसके बारे में लिखा था। –

1

बिल्कुल नहीं।

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

+0

धन्यवाद, मैंने इस दृष्टिकोण की कोशिश की है, लेकिन यह मेरे लिए काम नहीं करता है। मैं जावास्क्रिप्ट कोड को अपने सी # कक्षा में अप्रत्याशित फ़ील्ड कॉल करने की इजाजत देने के लिए आईईएक्सपांडो इंटरफ़ेस को अपनाने की कोशिश कर रहा हूं। उदाहरण के लिए, var o = new ActiveXObject ('mCom'); ओ। अरबी विपरीत फ़ील्ड = "फू"; कृपया ध्यान दें कि मेरी कक्षा में ArbitraryField मौजूद नहीं है। –

+0

क्या आपने अभी आईरफ़्लेक्चर को लागू करने का प्रयास किया है? गतिशील भाषाओं के साथ इंटरऑप के लिए आईडीस्पैच/आईईएक्सपांडो को लागू करने का यह तरीका है (कम से कम सी # 4.0 से पहले)। http://msdn.microsoft.com/en-us/library/system.reflection.ireflect.aspx मैंने हैशटेबल कार्यान्वयन के साथ यह सटीक चीज़ की है और यह अच्छी तरह से काम करता है – codekaizen

1

सी # 4.0 तक नहीं जो गतिशील लुकअप जोड़ता है और सीएलआर 4.0 पर आधारित है जो डीएलआर को शामिल करता है, और फिर यह कक्षा में सख्ती से नहीं जोड़ा जाएगा, क्योंकि कक्षाएं तस्वीर में नहीं होंगी।

+0

मुझे नहीं लगता कि यह संभव होगा सी # 4.0 में। मुझे लगता है कि आप मौजूदा प्रकारों को बदलने में सक्षम नहीं होंगे। हालांकि, मैं कल्पना कर सकता हूं कि आप कुछ गतिशील वस्तु (जैसे रूबी से आ रहे हैं) बना सकते हैं और इसे बदलने के बजाय। –

+0

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

6

सी # इसकी अनुमति नहीं देता है क्योंकि इसकी सभी कक्षाएं मेटाडेटा पर आधारित हैं। सीएलआर (सी # नहीं) रनटाइम (1) पर मेटाडेटा में फ़ील्ड जोड़ने की अनुमति नहीं देता है। यह एकमात्र तरीका है कि सी # रनिटमे पर एक फ़ील्ड जोड़ने में सक्षम होगा।

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

सी # 3.0 में, आपका सर्वोत्तम संसाधन प्रतिबिंब का उपयोग करना है। प्रवेश करें। लेकिन यह एक पूरी तरह से नई कक्षा बनाम एक मौजूदा एक बदल जाएगा।

(1) कुछ एपीआई हैं जैसे प्रोफाइलिंग एपीआई या ईएनसी जो इसकी अनुमति देते हैं लेकिन मुझे यकीन नहीं है कि उनकी क्षमताओं फ़ील्ड जोड़ने के लिए विस्तारित हैं या नहीं।

1

जैसा कि पहले से ही कहा गया है, यह संभव नहीं है। आपके प्रश्न का कारण क्या है?

class My { 
    Dictionary<string, object> data; 
    public My() { data = new Dictionary<string, object>(); } 
} 

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

+0

मेरा उद्देश्य IExpando इंटरफ़ेस को कार्यान्वित करना है। मेरा सुपर लक्ष्य जावास्क्रिप्ट कोड को सक्रिय रूप से ActiveX ऑब्जेक्ट में फ़ील्ड जोड़ने और "जावास्क्रिप्ट तरीके" में जोड़ने की अनुमति देना है। उदाहरण के लिए, var myobj = new ActiveXObject ('server.object'); myobj.ArbitraryField = "कुछ"; कृपया ध्यान दें कि ArbirtaryField मौजूद नहीं है –

1

, यह में क्या करना सी # 4.0 एक आसान तरीका के लिए this question देखें एक IDictionary, जो मान शब्दकोश में जोड़ा ऑब्जेक्ट के गुणों को हो जाती है के रूप में एक ExpandoObject कास्टिंग द्वारा। मैं इसे another answer of mine में दिखाता हूं जो दिखाता है कि वे वास्तव में गुण बन जाते हैं।

हालांकि, यह केवल ExpandoObject या उप-वर्गीकरण DynamicObject के उदाहरण के साथ संभव है।

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

0

शायद आप सजावट पैटर्न का उपयोग कर सकते हैं।

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

http://www.dofactory.com/Patterns/PatternDecorator.aspx

की [मैं सी # में गतिशील गुण कैसे बनाऊं?] (