2009-09-15 10 views
7

मैंने इस विषय से संबंधित सभी प्रश्नों को पढ़ा है, और वे सभी कारण बताते हैं कि struct पर एक डिफ़ॉल्ट कन्स्ट्रक्टर सी # में उपलब्ध नहीं है, लेकिन मुझे अभी तक कोई भी नहीं मिला है जो इस स्थिति से सामना करते समय कार्रवाई के सामान्य पाठ्यक्रम का सुझाव देता है।डिफ़ॉल्ट कन्स्ट्रक्टर को छिपाने के लिए अंधेरे से कक्षाओं को कक्षाओं में परिवर्तित करना?

स्पष्ट समाधान struct को class पर कनवर्ट करना और परिणामों से निपटना है।

क्या इसे struct के रूप में रखने के लिए अन्य विकल्प हैं?

मैं इस स्थिति में हमारी आंतरिक वाणिज्य API वस्तुओं में से एक के साथ भाग गया। डिजाइनर ने इसे class से struct में परिवर्तित कर दिया, और अब डिफ़ॉल्ट कन्स्ट्रक्टर (जो पहले निजी था) ऑब्जेक्ट को अमान्य स्थिति में छोड़ देता है।

मैंने सोचा कि अगर हम ऑब्जेक्ट को struct के रूप में रखने जा रहे हैं, तो राज्य की वैधता की जांच के लिए एक तंत्र पेश किया जाना चाहिए (IsValid संपत्ति की तरह कुछ)। मुझे बहुत प्रतिरोध के साथ मुलाकात की गई, और "जो कोई भी एपीआई का उपयोग करता है, उसे डिफॉल्ट कन्स्ट्रक्टर का उपयोग नहीं करना चाहिए," एक टिप्पणी जो निश्चित रूप से मेरी भौहें उठाती है। (नोट: प्रश्न में वस्तु "ठीक से" स्थिर कारखाने तरीकों के माध्यम से निर्माण किया है, और सभी अन्य निर्माताओं internal कर रहे हैं।)

हर किसी को सिर्फ अपने struct रों class तों को इस स्थिति में एक दूसरे सोचा बिना रूपांतरित होता है?

संपादित करें: मैं कैसे एक struct के रूप में इस प्रकार के ऑब्जेक्ट रखने के लिए के बारे में कुछ सुझाव देखना चाहेंगे - प्रश्न में वस्तु के ऊपर काफी बेहतर अनुकूल एक class के रूप में की तुलना में एक struct के रूप में है।

+0

यह एक अच्छा सवाल है। आप एक स्ट्रक्चर डिज़ाइन कर सकते हैं जैसे कि शून्य-आउट स्टेटस मान्य है, लेकिन वह अकेले हमेशा उपयोग करने योग्य एपीआई के लिए नहीं बनायेगा। यदि डिफ़ॉल्ट कन्स्ट्रक्टर है, तो कुछ लोग अनिवार्य रूप से इसे कॉल करेंगे क्योंकि यह उनके आईडीई में पॉप अप करेगा और कम से कम प्रतिरोध का मार्ग प्रदान करेगा। और इससे समस्याएं पैदा हो जाएंगी जो संकलक को पकड़ना चाहिए, या वे एक अपरिवर्तनीय शून्य-आउट संरचना पर गुण सेट करने का प्रयास करने में समय बर्बाद कर देंगे। मेरी इच्छा है कि सी # ने आपको डिफॉल्ट कन्स्ट्रक्टर को छिपाने की अनुमति दी है और लोगों को डिफ़ॉल्ट कॉल करने के लिए मजबूर किया है (...) यदि वे वास्तव में शून्य-आउट स्ट्रक्चर चाहते हैं। –

+0

असल में इस पर शोध करते हुए, मुझे लगता है कि उपयोगिता समस्या वास्तव में संकलक के बजाय इंटेलिजेंस में है। ऐसा प्रतीत होता है कि, एक समय पर, विजुअल स्टूडियो ने इंटेलिसेंस में डिफ़ॉल्ट कन्स्ट्रक्टर नहीं दिखाया, जो मेरी राय में, समझदारी करने वाली चीज़ है। लेकिन लोगों ने शिकायत की [यहां देखें] (http://stackoverflow.com/questions/1429495/blindly-converting-structs-to-classes-to-hide-the-default-constructor) और किसी बिंदु पर इसे बदलना होगा, चूंकि अब विजुअल स्टूडियो 2010 खाली कन्स्ट्रक्टर को पहले विकल्प के रूप में पॉप अप करता है। –

उत्तर

4

struct के लिए, आप प्रकार को डिज़ाइन करते हैं ताकि डिफ़ॉल्ट निर्मित उदाहरण (सभी शून्य फ़ील्ड) एक मान्य स्थिति हो। आप [] मनमाने ढंग से बिना किसी कारण के class के struct का उपयोग कर सकते हैं - एक अपरिवर्तनीय संदर्भ प्रकार का उपयोग करने में कुछ भी गलत नहीं है।

मेरे सुझाव:

  • यकीन है कि एक struct उपयोग करने का कारण मान्य है (एक [असली] प्रोफाइलर महत्वपूर्ण प्रदर्शन की समस्याओं के लिए एक बहुत हल्के वस्तु की भारी आवंटन से उत्पन्न पता चला)।
  • इस प्रकार का डिज़ाइन करें ताकि डिफ़ॉल्ट निर्मित उदाहरण मान्य हो।
  • यदि प्रकार का डिज़ाइन देशी/COM इंटरऑप बाधाओं द्वारा निर्धारित किया गया है, तो कार्यक्षमता को लपेटें और रैपर (निजी नेस्टेड प्रकार) के बाहर struct का पर्दाफाश न करें। इस तरह आप आसानी से बाध्य प्रकार की आवश्यकताओं के उचित उपयोग को दस्तावेज और सत्यापित कर सकते हैं।
+0

अच्छा जवाब।आश्चर्यजनक रूप से पर्याप्त है, ऊपर दिए गए मेरे विशेष मामले के लिए, आपने जो भी कहा है, उनमें से कोई भी लागू नहीं होता है, क्योंकि ऑब्जेक्ट एक संदर्भ प्रकार होने पर समस्याओं को आसानी से कोड में पेश किया जाता है ... इसलिए इसे एक संरचना में क्यों परिवर्तित किया गया था। लेकिन कई अन्य मामलों में, एक अपरिवर्तनीय संदर्भ प्रकार का उपयोग एक व्यवहार्य समाधान होगा। –

1

इसका कारण यह है कि एक संरचना (System.ValueType का एक उदाहरण) विशेष रूप से सीएलआर द्वारा इलाज किया जाता है: यह सभी क्षेत्रों 0 (या डिफ़ॉल्ट) के साथ शुरू किया जाता है। आपको वास्तव में एक बनाने की भी आवश्यकता नहीं है - बस इसे घोषित करें। यही कारण है कि डिफ़ॉल्ट कन्स्ट्रक्टर की आवश्यकता है।

आप दो तरह से इस के आसपास मिल सकती है: नेट 2.0 में और

  1. अगर यह एक वैध struct है अगर है की तरह एक प्रॉपर्टी बनाएं इंगित करने के लिए, की तरह आप से संकेत मिलता है
  2. Nullable < टी > उपयोग करने पर विचार एक अनियमित (शून्य) संरचना की अनुमति देने के लिए।

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

0

कारण है कि वहाँ एक डिफ़ॉल्ट निर्माता को परिभाषित करने की कोई संभावना नहीं निम्नलिखित अभिव्यक्ति के रूप में रेखांकित किया गया है:

new MyStruct[1000]; 

आप 3 विकल्प यहाँ

  1. डिफ़ॉल्ट निर्माता 1000 बुला मिल गया है समय, या
  2. भ्रष्ट डेटा बनाते हुए (ध्यान दें कि एक संरचना में संदर्भ हो सकते हैं; यदि आप संदर्भ को प्रारंभ या खाली नहीं करते हैं, तो आप संभावित रूप से मनमानी ज्ञापन तक पहुंच सकते हैं आरई), या
  3. ज़ीरो (बाइट स्तर पर) के साथ आवंटित स्मृति को खाली करें।

.NET दोनों structs और वर्गों के लिए समान है: फ़ील्ड और सरणी तत्व शून्य के साथ खाली हो जाते हैं। यह structs और कक्षाओं और कोई असुरक्षित कोड के बीच अधिक संगत व्यवहार भी प्राप्त करता है। यह .NET ढांचे को new byte[1000] जैसे कुछ विशेषज्ञ नहीं करने की अनुमति देता है।

और यह structs के लिए डिफ़ॉल्ट कन्स्ट्रक्टर है .NET मांग करता है और स्वयं का ख्याल रखता है: सभी बाइट्स शून्य।

अब, यह संभाल करने के लिए, आप विकल्पों में से एक जोड़े को मिल गया है:

  • struct (जैसे HasValueNullable पर) के लिए एक Am-मैं-प्रारंभ संपत्ति जोड़ें।
  • शून्य आउट आउट स्ट्रक्चर को वैध मान होने दें (जैसे 0 दशमलव के लिए मान्य मान है)।
संबंधित मुद्दे