2012-04-30 30 views
16

मुझे ऑब्जेक्ट्स (कस्टम क्लासेस) के एक विषम List बनाने की आवश्यकता है। मेरा पहला विचार List<ISomeMarkerInterface> बनाना था, लेकिन मैंने जल्दी से सीखा कि यह वही नहीं है जो मैं चाहता हूं। मेरा अगला विचार List<dynamic> था और यह एक बुरा विचार प्रतीत नहीं होता था। हालांकि, मैं कुछ शोध कर रही है और इस article about boxing and unboxing भर में और उदाहरण में आया था, वे मूल रूप से कर रहे हैं मैं List<Object> क्या का उपयोग कर करना चाहते हैं।सूची <Object> बनाम सूची <dynamic>

तथ्य यह है कि dynamic रनटाइम पर मूल्यांकन किया जाएगा और संकलन समय पर Object, List<dynamic> और List<Object> के बीच अंतर क्या है के अलावा? क्या वे अनिवार्य रूप से एक ही बात नहीं हैं?

+2

आपको एक ही सूची में विषम वस्तुओं को स्टोर करने की आवश्यकता क्यों है? बस उत्सुक ... –

+0

आपको डायनामिक बनाम ऑब्जेक्ट की तलाश करनी चाहिए, इस थ्रेड को देखें, शायद यह आपके उत्तर का जवाब देगा http://stackoverflow.com/questions/3442821/dynamic-vs-object-type – Habib

+0

मेरे पास एक कक्षा है जहां एक गुणों का उस वर्ग के लिए प्रासंगिक वस्तुओं का संग्रह है जो एक ही प्रकार के नहीं हैं, लेकिन समूह के रूप में प्रासंगिक हैं। – Jason

उत्तर

19

इसमें 3 "सामान्य" प्रकार (हालांकि सभी वेब वास्तविक प्रकार के होते हैं) सी # में कर रहे हैं: वस्तु, वर और गतिशील।

वस्तु

एक वास्तविक प्रकार, किसी भी अन्य प्रकार की तरह, एक विशेष नियम के साथ: अगर एक प्रकार के वारिस नहीं है, यह वस्तु से विरासत। इस से, यह इस प्रकार है कि सभी प्रकार, वस्तु से विरासत प्रत्यक्ष या परोक्ष रूप।

जोर: वस्तु एक प्रकार है। एक ऑब्जेक्ट ऑब्जेक्ट प्रकार का हो सकता है, और इस प्रकार के तरीके ToString() जैसे हैं। चूंकि सबकुछ ऑब्जेक्ट से प्राप्त होता है, इसलिए सब कुछ ऑब्जेक्ट में उड़ाया जा सकता है। जब आप एक वस्तु संदर्भ के लिए एक वस्तु असाइन करते हैं, आप upcasting कर रहे हैं बस जब आप एक पशु संदर्भ जहां हाथीपशु से विरासत के लिए एक हाथी प्रकार वस्तु आवंटित की तरह।

SomeType x = new SomeType(); 
object obj = x; 
obj.DoSomething(); 
  • obj प्रकार वस्तु संकलन समय पर की जा रही है के रूप में माना जाता है, और प्रकार वस्तु कार्यावधि में (जो तार्किक है, क्योंकि यह एक वास्तविक प्रकार है के लिए किया जाएगा - objओब के रूप में, के रूप में वस्तु इतना ही नहीं प्रकार)
  • obj.DoSomething() का हो सकता है एक संकलन समय त्रुटि का कारण होगा घोषित किया जाता है ject में यह विधि नहीं है, भले ही कुछ टाइप टाइप करें।

वार

यह एक वास्तविक प्रकार नहीं है, इसके लिए केवल आशुलिपि है "संकलक, असाइनमेंट के दाईं ओर के आधार पर मेरे लिए प्रकार यह पता लगाने"।

SomeType x = new SomeType(); 
var obj = x; 
obj.DoSomething(); 
  • obj "var" के बजाय प्रकार SomeType संकलन समय पर की जा रही है के रूप में माना जाता है, और प्रकार SomeType कार्यावधि में की हो जाएगा, जैसे कि आपने लिखा था "SomeType" ।
  • अगर SomeType एक विधि DoSomething() है, इस कोड काम करेंगे
  • अगर SomeType विधि नहीं है, कोड एक संकलन समय त्रुटि

कारण होगा गतिशील

यह एक ऐसा प्रकार है जो कंपाइलर को चर पर संकलन-समय प्रकार की जांच को अक्षम करने के लिए कहता है। संकलन-समय और रन-टाइम पर एक ऑब्जेक्ट को डायनामिक टाइप करने के रूप में माना जाता है।

SomeType x = new SomeType(); 
dynamic obj = x; 
obj.DoSomething(); 
  • obj प्रकार के समय
  • DoSomething() है गतिशील संकलन पर और चलाते हैं SomeType एक विधि है, इस कोड काम करेंगे
  • अगर SomeType नहीं करता ' टी विधि है, कोड संकलित होगा, लेकिन रन-टाइम
  • पर अपवाद फेंक देगा ई कि गतिशील बहुत आसानी से अपवाद पैदा कर सकता है अगर लापरवाही प्रयोग किया है: यदि एक्स एक प्रकार है कि DoSomething विधि नहीं है की है

    public void f(dynamic x) 
    { 
        x.DoSomething(); 
    } 
    

यह एक अपवाद फेंक होगा, लेकिन यह अभी भी इसे कॉल करना संभव होगा और किसी ऑब्जेक्ट को संकलन-समय त्रुटि के बिना पैरामीटर के रूप में पास करना होगा, जिससे त्रुटि केवल रन-टाइम पर दिखाई देगी, और संभवतः केवल विशिष्ट परिस्थितियों में - एक संभावित बग। इसलिए यदि आप कक्षा के किसी भी प्रकार के सार्वजनिक इंटरफ़ेस में गतिशीलता का उपयोग करते हैं, तो आपको हमेशा प्रतिबिंब का उपयोग करके रनटाइम पर मैन्युअल रूप से टाइप-चेक करना चाहिए, ध्यान से अपवादों से निपटना चाहिए, या इसे पहले स्थान पर नहीं करना चाहिए।

नोट: ऑब्जेक्ट का उल्लेख कभी भी इसके प्रकार को कभी नहीं बदलता है। जबकि objऑब्जेक्ट, x हो सकता है कि यह अभी भी कुछ टाइप है।

+4

- 1 यह कहने के लिए कि 'गतिशील' वास्तविक प्रकार नहीं है ('var' से बहुत अलग है जो एक वास्तविक प्रकार _isn't_ नहीं है, जैसा कि आप सही ढंग से कहते हैं)। 'गतिशील' निश्चित रूप से सी # में एक प्रकार है, यह एक _static_ प्रकार भी है, लेकिन 'गतिशील' प्रकार का एक वस्तु स्थिर प्रकार की जांच को बाईपास कर देगा। अधिक जानकारी के लिए सी # भाषा विशिष्टता या इस लिंक (http://msdn.microsoft.com/en-us/library/dd264736.aspx) के §4.7 देखें। – Nailuj

+0

ओह, मैंने इसे ठीक किया। मुझे पहले अनुमान लगाया जाना चाहिए था। : डी I हालांकि डायनामिक को तत्काल असाइनमेंट रन-टाइम पर उपयुक्त प्रकार के लिए हल किया गया था और वास्तव में कभी भी "गतिशील" के रूप में टाइप नहीं किया गया था, लेकिन स्पष्ट रूप से यह मामला नहीं है। – svinja

+1

अब नहीं -1 :) – Nailuj

2

अंतर यह है कि यह एक संकलन समय त्रुटि हो सकता है अगर आप वस्तु का उपयोग करें और आप अपनी वस्तु के कुछ सदस्य तक पहुँचने का प्रयास (क्योंकि वस्तु इस सदस्य नहीं है) है। काम करने के लिए आपको यह जानने की जरूरत है कि किस प्रकार का है और इसे कास्ट करें।

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

हालांकि यदि ऐसा है तो एक और स्पष्ट समाधान है: आप इस सदस्य के साथ एक इंटरफ़ेस परिभाषित कर सकते हैं और फिर अपनी सभी विषम वस्तुओं को कार्यान्वित कर सकते हैं और आपकी सूची List<IYourInterface> हो सकती है।

ध्यान रखें कि, गतिशील प्रकार के संकल्प के कारण गतिशील का प्रदर्शन थोड़ा और खराब हो सकता है।

+0

गतिशील का उपयोग करके, क्या आप किसी सदस्य के अस्तित्व की जांच कर सकते हैं और जारी रख सकते हैं कि यह त्रुटि को फेंकने के बिना नहीं है? जावास्क्रिप्ट में तरह की तरह आप कैसे कुछ कर सकते हैं जैसे 'if (data.something) {} '? – Jason

+1

इसे प्रतिबिंब कहा जाता है। आप इसका उपयोग * गतिशील * के साथ या उसके बिना कर सकते हैं। GetType(), GetMethod(), आदि – svinja

+0

+1 देखें, यदि आप प्रतिबिंब मार्ग पर जा रहे हैं, तो आप ऑब्जेक्ट का उपयोग भी कर सकते हैं (लेकिन मैं अभी भी उस के शीर्ष पर मार्कर इंटरफ़ेस की अनुशंसा करता हूं) – MattDavey

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