क्या विशेषताएँ C # में गतिशील रूप से जोड़ी जा सकती हैं?


143

क्या रनटाइम पर विशेषताओं को जोड़ना संभव है या रनटाइम पर एक विशेषता के मूल्य को बदलना है?

जवाबों:


67

विशेषताएँ स्थिर मेटाडेटा हैं। असेंबली, मॉड्यूल, प्रकार, सदस्य, पैरामीटर और रिटर्न मान C # में प्रथम श्रेणी के ऑब्जेक्ट नहीं हैं (जैसे, System.Typeक्लास केवल एक प्रकार का एक प्रतिबिंबित प्रतिनिधित्व है)। आप एक प्रकार के लिए एक विशेषता का एक उदाहरण प्राप्त कर सकते हैं और गुणों को बदल सकते हैं यदि वे लिखने योग्य हैं, लेकिन यह उस प्रकार को लागू करने पर विशेषता को प्रभावित नहीं करेगा।


68

यह वास्तव में इस बात पर निर्भर करता है कि आप क्या हासिल करना चाहते हैं।

System.ComponentModel.TypeDescriptor सामान प्रकार, गुण और वस्तु उदाहरणों विशेषताएं जोड़ने का तरीका इस्तेमाल किया जा सकता है, और यह सीमा आप इसका इस्तेमाल करने के साथ-साथ उन गुणों को पुनः प्राप्त करने के लिए है कि नहीं है। यदि आप वह कोड लिख रहे हैं जो उन विशेषताओं का उपभोग करता है, और आप उन सीमाओं के भीतर रह सकते हैं, तो मैं निश्चित रूप से इसका सुझाव दूंगा।

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


7
दरअसल, ज्यादातर डेटा-बाइंडिंग उपयोग करता है TypeDescriptor- न कि सिर्फ PropertyGrid
मार्क Gravell

1
सिल्वरलाइट परियोजना में संपत्ति-मेटाडेटा विशेषताओं को जोड़ने के लिए कोई भी समाधान (जहां TypeDescriptorऔर TypeDescriptionProviderलागू नहीं किया गया है?
Shimmy Weitzhandler

1
नोट करने के लिए महत्वपूर्ण, TypeDescriptor.GetAttributes () डुप्लिकेट विशेषताओं को संभालता नहीं है। यह केवल विशेषता प्रकार के अंतिम का चयन करता है। Ex [Attr(1), Attr(2), Attr(3)]केवल Attr(3)पाया जाता है।
ओमुसमा

11

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


10

खैर, बस अलग होने के लिए, मुझे एक लेख मिला जो रिफ्लेक्शन का उपयोग करता है। ऐसा करने के लिए मानें।

यहाँ लिंक है: http://www.codeproject.com/KB/cs/dotnetattributes.aspx , आप लेख के निचले भाग में कुछ टिप्पणियों पर भी गौर करना चाहेंगे, क्योंकि संभावित दृष्टिकोणों पर चर्चा की गई है।


10
ध्यान दें कि आप परावर्तन के साथ रनटाइम पर विशेषताएँ बना सकते हैं। वर्गों का चयन करें, लेकिन आप उन्हें उन कक्षाओं में बाँध सकते हैं, जिन्हें आपने एमिट पैकेज के साथ बनाया है और मौजूदा लोगों के लिए नहीं।
पैनोस

क्या बेकार जवाब =)) हम सभी मौजूदा वर्गों के बारे में परवाह करते हैं, न कि गतिशील।
होपलेस

@ अनुपयोगी, आप उपवर्ग YourClassमें हो सकते हैं YourRuntimeClassWithAttributes
Motes

@ आप निश्चित नहीं हैं कि आपका क्या मतलब है, मेरी कक्षाएं सभी पहले से परिभाषित हैं, इसका मतलब है कि सभी आधार वर्ग (कि मेरी कक्षाएं विरासत में मिली हैं) को भी पहले से परिभाषित / निर्धारित किया जाना चाहिए। मैं इसके लिए किसी भी तरीके के बारे में सोच भी नहीं सकता हूं, क्योंकि इसे प्रतिबिंबित करने के लिए गतिशील रूप से बनाया गया है।
होपलेस

1
@Hopeless, यदि आप एक मौजूदा वर्ग में गतिशील रूप से विशेषताओं को जोड़ना चाहते हैं, तो आप YourClassइसे रनटाइम पर उप- वर्ग कर सकते हैं और एक समान श्रेणी उत्पन्न कर सकते हैं जिसमें थोड़ा अलग नाम भी हो सकता है जिसमें वांछित गतिशील रूप से निर्मित विशेषताएँ हैं, और बहुरूपता अभी भी पहचान करने के लिए टाइप कोड की अनुमति देगा। आपके बेसकेल्स।
Motes

4

नहीं यह नहीं।

विशेषताएँ मेटा-डेटा हैं और संकलित असेंबली में बाइनरी-फॉर्म में संग्रहीत हैं (यही कारण है कि आप केवल उनमें सरल प्रकार का उपयोग कर सकते हैं)।


3

मैं ऐसा नहीं मानता। यहां तक ​​कि अगर मैं गलत हूं, तो आप जो सबसे अच्छी उम्मीद कर सकते हैं, वह उन्हें पूरे प्रकार में जोड़ रहा है, कभी भी एक प्रकार का उदाहरण नहीं ।


22
TypeDescriptor.AddAttributes (ऑब्जेक्ट, एट्रिब्यूट []) लक्ष्य घटक उदाहरण में वर्ग-स्तरीय विशेषताएँ जोड़ता है।
पीटर वॉन

3

यदि आपको गतिशील रूप से कुछ करने में सक्षम होने की आवश्यकता है, तो सी # विशेषताएँ रास्ता नहीं हैं। डेटा को xml में संग्रहीत करने पर ध्यान दें। मैंने हाल ही में एक प्रोजेक्ट किया था जिसे मैंने डब्ल्यू / एट्रिब्यूट्स शुरू किया था, लेकिन अंततः सीरीज़ डब्ल्यू / एक्सएमएल में चला गया।


1
शायद यह एक सुंदर तरीका नहीं है, लेकिन यह कई अन्य पुस्तकालयों का उपयोग करने का तरीका है, और उन पुस्तकालयों के व्यवहार को अनुकूलित करने के लिए, हमें प्रतिबिंब =) के साथ खेलने की आवश्यकता है) वास्तव में एक गतिरोध है।
होपलेस

3

आपको करने की आवश्यकता क्यों है? विशेषताएँ प्रतिबिंब के लिए अतिरिक्त जानकारी देती हैं, लेकिन यदि आप बाहरी रूप से जानते हैं कि आपको कौन से गुण चाहिए, तो आपको उनकी आवश्यकता नहीं है।

आप डेटाबेस या संसाधन फ़ाइल में मेटा डेटा को बाहरी रूप से अपेक्षाकृत आसानी से संग्रहीत कर सकते हैं।


1
बॉयलरप्लेट उन्मूलन। क्या यह आसान नहीं होगा यदि आपके पास वर्ग के भीतर कोड के आधार पर स्वचालित रूप से एक विशेषता उत्पन्न हो सकती है? मैं एसक्यूएल सीएलआर ऑब्जेक्ट्स में बॉयलरप्लेट को कम करने के लिए कुछ इस तरह का पता लगाने की कोशिश कर रहा हूं। अन्य भाषाओं में आसान होगा ... paulgraham.com/avg.html
डंकन

1

मैंने सफलता के बिना System.ComponentModel.TypeDescriptor के साथ बहुत कोशिश की। इसका मतलब यह नहीं है कि यह काम नहीं कर सकता है लेकिन मैं इसके लिए कोड देखना चाहूंगा।

काउंटर पार्ट में, मैं कुछ एट्रीब्यूट मान बदलना चाहता था। मैंने 2 कार्य किए जो उस उद्देश्य के लिए ठीक काम करते हैं।

        // ************************************************************************
        public static void SetObjectPropertyDescription(this Type typeOfObject, string propertyName,  string description)
        {
            PropertyDescriptor pd = TypeDescriptor.GetProperties(typeOfObject)[propertyName];
            var att = pd.Attributes[typeof(DescriptionAttribute)] as DescriptionAttribute;
            if (att != null)
            {
                var fieldDescription = att.GetType().GetField("description", BindingFlags.NonPublic | BindingFlags.Instance);
                if (fieldDescription != null)
                {
                    fieldDescription.SetValue(att, description);
                }
            }
        }

        // ************************************************************************
        public static void SetPropertyAttributReadOnly(this Type typeOfObject, string propertyName, bool isReadOnly)
        {
            PropertyDescriptor pd = TypeDescriptor.GetProperties(typeOfObject)[propertyName];
            var att = pd.Attributes[typeof(ReadOnlyAttribute)] as ReadOnlyAttribute;
            if (att != null)
            {
                var fieldDescription = att.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
                if (fieldDescription != null)
                {
                    fieldDescription.SetValue(att, isReadOnly);
                }
            }
        }

-7

जावा में मैं एक मानचित्र का उपयोग करके और की-वैल्यू कोडिंग पर अपना खुद का कार्यान्वयन करके इसके चारों ओर काम करता था।

http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/KeyValueCoding.html


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