2011-11-16 12 views
12

मेरे पास struct है जिसमें दो सूचियां हैं:क्या एक कन्स्ट्रक्टर का उपयोग किये बिना संरचना के सदस्यों को शुरू करने का कोई तरीका है?

struct MonthData 
{ 
    public List<DataRow> Frontline; 
    public List<DataRow> Leadership; 
} 

हालांकि, जब मैं संरचना बनाई जाती है तो मैं दोनों को प्रारंभ करना चाहता हूं। यदि मैं कोशिश करता हूं:

struct MonthData 
{ 
    public List<DataRow> Frontline = new List<DataRow>(); 
    public List<DataRow> Leadership = new List<DataRow>(); 
} 

फिर मुझे मिलता है:

Error 23 'MonthData.Frontline': cannot have instance field initializers in structs 
... 

चूंकि structs में पैरामीटर रहित कन्स्ट्रक्टर नहीं हो सकते हैं, इसलिए मैं इसे केवल कन्स्ट्रक्टर में सेट नहीं कर सकता। अब तक, मैं केवल निम्नलिखित विकल्पों को देख सकता हूं:

  1. जब मैं MonthData
  2. का उदाहरण बनाता हूं तो दोनों गुणों को आरंभ करें संरचना के बजाय कक्षा का उपयोग करें
  3. पैरामीटर के साथ एक कन्स्ट्रक्टर बनाएं और
  4. का उपयोग करें
  5. उन गुणों के लिए गेटर्स और सेटर्स बनाएं जो उन्हें आलसी शुरू करें।

इसके लिए अनुशंसित दृष्टिकोण क्या है? अभी, मैं सोच रहा हूं कि यह एक वर्ग सबसे अच्छा विचार है।

+0

इसे कक्षा बनाएं। एक बार जब आप संरचना में संदर्भ प्रकार जोड़ते हैं, तो यह वास्तव में एक मूल्य प्रकार नहीं है। – drdwilcox

+1

क्या यह वास्तव में एक संदर्भ प्रकार (वर्ग) बनाम एक मान प्रकार (संरचना) बनाने के लिए ठीक है? यदि ऐसा है, तो आगे बढ़ें और इसे कक्षा बनाएं। – BoltClock

+0

हाँ, इस प्रकार के लिए एक संरचना होने के लिए यह समझ में नहीं आता है। –

उत्तर

7

आपको इसके बजाय कक्षा का उपयोग करना चाहिए। MSDN से:

सामान्य में, वर्गों और अधिक जटिल व्यवहार मॉडल करने के लिए उपयोग किया जाता है, या बाद में एक वर्ग वस्तु बनाई गई है कि इरादा है डेटा संशोधित करने की। स्ट्रक्चर छोटे डेटा संरचनाओं के लिए सबसे उपयुक्त हैं जिनमें मुख्य रूप से डेटा होता है जिसे संरचना के निर्माण के बाद संशोधित करने का इरादा नहीं है।

1

एक निर्माता के साथ ऐसा करने का कोई तरीका नहीं है। सीएलआर स्ट्रक्चर के उदाहरण बना सकता है और बना देगा, बस स्मृति को शुरू करने में शून्य हो और किसी भी सीटीओ ओवरहेड से बचें। हालांकि आप इस ज्ञान का लाभ उठा सकते हैं और प्रारंभिक गुणों में देरी कर सकते हैं जिनके समान प्रभावशाली प्रभाव पड़ता है।

उदाहरण के लिए:

struct MonthData { 
    private bool m_initialized; 
    private List<DataRow> m_frontLine; 
    private List<DataRow> m_leaderShip; 

    public List<DataRow> FrontLine { 
    get { 
     EnsureInitialized(); 
     return m_frontLine; 
    } 
    } 

    public List<DataRow> LeaderShip { 
    get { 
     EnsureInitialized(); 
     return m_leaderShip; 
    } 
    } 

    void EnsureInitialized() { 
    if (!m_initialized) { 
     m_initialized = true; 
     m_frontLine = new List<DataRow>(); 
     m_leaderShip = new List<DataRow>(); 
    } 
    } 
} 
+0

हाँ मुझे लगता है कि ऐसा कुछ करने से मेरी दूसरी पसंद होगी। लेकिन यह एक साधारण वस्तु है, मैं यहां दूसरों से सहमत हूं और सोचता हूं कि यह सिर्फ एक वर्ग होना चाहिए - खासकर जब इसमें केवल दो संदर्भ प्रकार हैं। –

+1

@ माइक क्रिस्टेनसेन सामान्य रूप से यह शायद एक वर्ग होना चाहिए। मेरा जवाब अधिक है "यदि आप कोने में फंस जाते हैं और एक स्ट्रक्चर का उपयोग करना चाहते हैं तो यह करें" – JaredPar

+0

हाँ मुझे लगता है कि कारखाना दृष्टिकोण और आलसी प्रारंभिक दृष्टिकोण बहुत अच्छा है - मैं भविष्य में डिजाइन चुनौतियों के लिए उन्हें ध्यान में रखूंगा । –

6

तुम सिर्फ वाक्य रचना के बारे में पूछ रहे हैं ... इमारत कोशिश करते हैं और बदले में एक स्थिर कारखाने का उपयोग कर ... सामान्य में, structs चीजें हैं जो अपरिवर्तनीय हैं के लिए इस्तेमाल किया जाना चाहिए, और एक कारखाना, (जो एक निजी कन्स्ट्रक्टर कहता है) एक सार्वजनिक कन्स्ट्रक्टर का उपयोग करने के बजाय एक अपरिवर्तनीय प्रकार के लिए एक बेहतर दृष्टिकोण है।

struct MonthData 
    {  
     public List<DataRow> Frontline; 
     public List<DataRow> Leadership; 
     private MonthData(List<DataRow> frontLine = null, 
         List<DataRow> leadership = null) 
     { 
     Frontline = frontLine?? new List<DataRow>(); 
     Leadership = leadership?? new List<DataRow>(); 
     } 
     public static MonthData Factory(
      List<DataRow> frontLine= null, 
      List<DataRow> leadership= null) 
     { return new MonthData(frontLine, leadership); } 
    } 
+0

यह निश्चित रूप से एक दिलचस्प दृष्टिकोण है। जैसा कि आपने बताया है, मेरी वस्तु अपरिवर्तनीय नहीं है (हालांकि यह एक संग्रह है जहां चीजों को बाहर-बाहर जोड़ दिया जाएगा इसका जीवन) तो शायद एक वर्ग सबसे अच्छा है। हालांकि विचार के लिए +1। –

+0

मुझे स्थिर फैक्ट्री विधि विचार पसंद है। हालांकि, आप कर सकते हैं structs में उदाहरण फ़ील्ड प्रारंभकर्ता नहीं है। तो 'सार्वजनिक सूची फ्रंटलाइन = नई सूची () 'संकलित नहीं होने जा रही है। –

+0

@ जिम मिस, हां, संपादन के बिना कट और चिपकाया गया ... इसे ठीक किया गया ... –

6

आप संदर्भ प्रकार (List<T>) इस प्रकार मान प्रकार के रूप में एक struct के उपयोग का उपयोग कर रहे अपने struct में वैसे भी, मेरे लिए कोई मतलब नहीं होगा। मैं बस एक कक्षा के साथ जाना होगा।

+0

एक और विकल्प 'इमटेबलएरे ' का उपयोग करना होगा और @ चार्ल्सब्रेटाना द्वारा उल्लिखित बिल्डर विधि के साथ जाना होगा। – m93a

1

यह अच्छा होगा अगर सीएलआर ने गारंटी देने के साधनों की अनुमति दी हो कि संरचना प्रकार की चीजें कुछ प्रारंभिक कोड हो सकती हैं, इससे पहले कि वे इस तरह के कोड के बाहर कुछ भी दिखाई दे सकें। ऐसा करना संभव होता है, यहां तक ​​कि संरचना प्रकार की सरणी बनाते समय, सीएलआर पास करके सरणी के संदर्भ से पहले सरणी के सभी अलग-अलग तत्वों को संदर्भित करके स्वयं को कहीं भी उजागर किया गया था। दुर्भाग्य से, यदि सरणी के निर्माण के दौरान एक अपवाद फेंक दिया गया तो यह एक अजीब स्थिति का कारण बनता।यदि रचनाकारों के पास कोई साइड इफेक्ट नहीं होता है, तो कोई समस्या नहीं होगी - केवल सरणी को छोड़ दें और दिखाएं कि सफलतापूर्वक निर्मित वस्तुओं को कभी भी अस्तित्व में नहीं रखा गया है। साइड इफेक्ट्स के साथ रचनाकार, हालांकि, कुछ कठिनाइयों का कारण बन सकते हैं।

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

उत्परिवर्तनीय structs बुरा नहीं हैं; मैं, अगर कुछ भी, उनके मजबूत समर्थकों में से एक हूँ। फिर भी, म्यूटेबल structs के .NET के हैंडलिंग में कुछ सीमाएं हैं, और इस प्रकार कई परिस्थितियां हैं जहां मूल्य-प्रकार अर्थशास्त्र उचित होगा, लेकिन नेट सीमाएं इस तरह के अर्थशास्त्र को उचित रूप से प्रदान करना असंभव बनाती हैं।

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

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