पालन करने का सामान्य नियम यह है कि संबंधित संपत्तियों के छोटे, सरल (एक-स्तरीय) संग्रह होने चाहिए, जो एक बार बनाए जाने के बाद अपरिवर्तनीय हैं; कुछ और के लिए, एक वर्ग का उपयोग करें।
सी # अच्छा है कि संरचना और कक्षाओं में परिभाषित कीवर्ड के अलावा घोषणा में कोई स्पष्ट अंतर नहीं है; इसलिए, यदि आपको लगता है कि आपको किसी वर्ग के लिए एक संरचना को "अपग्रेड" करने की आवश्यकता है, या एक संरचना के लिए एक कक्षा को "डाउनग्रेड" करना है, तो यह ज्यादातर कीवर्ड को बदलने का एक सरल मामला है (कुछ अन्य गोचर्स हैं; संरचनाएं व्युत्पन्न नहीं हो सकती हैं; किसी अन्य वर्ग या संरचना प्रकार से, और वे स्पष्ट रूप से एक डिफ़ॉल्ट पैरामीटर रहित कंस्ट्रक्टर को परिभाषित नहीं कर सकते हैं)।
मैं कहता हूं "ज्यादातर", क्योंकि संरचनाओं के बारे में जानने के लिए अधिक महत्वपूर्ण बात यह है कि, क्योंकि वे मूल्य प्रकार हैं, उन्हें कक्षाओं (संदर्भ प्रकार) की तरह व्यवहार करने से दर्द और एक आधा खत्म हो सकता है। विशेष रूप से, संरचना के गुणों को परिवर्तनशील बनाने से अप्रत्याशित व्यवहार हो सकता है।
उदाहरण के लिए, मान लें कि आपके पास एक क्लास है सिंपलक्लास दो गुणों के साथ, ए और बी। आप इस वर्ग की एक प्रति को तत्काल करते हैं, ए और बी को इनिशियलाइज़ करते हैं, और फिर दूसरी विधि से उदाहरण को पास करते हैं। वह विधि आगे चलकर ए और बी को कॉलिंग फ़ंक्शन (उदाहरण को बनाने वाला) को संशोधित करती है, आपके इंस्टेंस के ए और बी को उनके द्वारा दिए गए मानों को कहा जाएगा।
अब, आप इसे एक संरचना बनाते हैं। गुण अभी भी परिवर्तनशील हैं। आप पहले के समान ही सिंटैक्स के साथ समान संचालन करते हैं, लेकिन अब, ए और बी के नए मान विधि को कॉल करने के बाद नहीं हैं। क्या हुआ? खैर, आपकी कक्षा अब एक संरचना है, जिसका अर्थ है कि यह एक मूल्य प्रकार है। यदि आप किसी विधि के लिए एक मान प्रकार पास करते हैं, तो डिफ़ॉल्ट (एक आउट या रेफ कीवर्ड के बिना) "मूल्य से" पास करना है; आवृत्ति की एक उथली प्रतिलिपि विधि द्वारा उपयोग के लिए बनाई गई है, और तब नष्ट कर दिया जाता है जब विधि को प्रारंभिक उदाहरण बरकरार रखा जाता है।
यह और भी भ्रामक हो जाता है यदि आपको अपनी संरचना के सदस्य के रूप में एक संदर्भ प्रकार होना चाहिए (अस्वीकृत नहीं है, लेकिन वस्तुतः सभी मामलों में बहुत बुरा अभ्यास); वर्ग क्लोन नहीं किया जाएगा (केवल संरचना का संदर्भ), इसलिए संरचना में परिवर्तन मूल वस्तु को प्रभावित नहीं करेगा, लेकिन संरचना के उपवर्ग में परिवर्तन कॉल कोड से आवृत्ति को प्रभावित करेगा। यह बहुत आसानी से बहुत असंगत राज्यों में उत्परिवर्तनीय संरचनाएं डाल सकता है जो वास्तविक समस्या है जहां से दूर एक लंबा रास्ता तय कर सकते हैं।
इस कारण से, C # पर प्रत्येक प्राधिकरण हमेशा आपकी संरचनाओं को अपरिवर्तनीय बनाने के लिए कहता है; उपभोक्ता को केवल एक वस्तु के निर्माण पर गुणों के मूल्यों को निर्दिष्ट करने की अनुमति दें, और उस उदाहरण के मूल्यों को बदलने के लिए कभी कोई साधन प्रदान न करें। पठनीय क्षेत्र, या केवल गुण प्राप्त करें, नियम हैं। यदि उपभोक्ता मूल्य को बदलना चाहता है, तो वे पुराने के मूल्यों के आधार पर एक नई वस्तु बना सकते हैं, जो वे चाहते हैं, या वे एक विधि कह सकते हैं, जो ऐसा ही करेगा। यह उन्हें आपकी संरचना के एक एकल उदाहरण को एक वैचारिक "मूल्य" के रूप में व्यवहार करने के लिए मजबूर करता है, जो अन्य सभी से अविभाज्य और अलग है (लेकिन संभवतः समान है)। यदि वे आपके प्रकार द्वारा संग्रहीत "मान" पर एक ऑपरेशन करते हैं, तो उन्हें एक नया "मान" मिलता है जो उनके प्रारंभिक मूल्य से अलग होता है,
एक अच्छे उदाहरण के लिए, DateTime प्रकार देखें। आप किसी भी समय तिथि उदाहरण के किसी भी क्षेत्र को सीधे असाइन नहीं कर सकते हैं; आपको या तो एक नया बनाना होगा, या मौजूदा एक विधि पर कॉल करना होगा जो एक नया उदाहरण उत्पन्न करेगा। इसका कारण यह है कि दिनांक और समय संख्या 5 की तरह एक "मान" है, और संख्या 5 में एक नए मूल्य में परिवर्तन होता है जो 5. नहीं है। सिर्फ इसलिए कि 5 + 1 = 6 का अर्थ 5 नहीं है अब 6 है क्योंकि आपने इसमें 1 जोड़ा है। डेटटाइम्स उसी तरह काम करते हैं; 12:00 "मिनट" नहीं बनता है 12:01 यदि आप एक मिनट जोड़ते हैं, तो आपको इसके बजाय एक नया मान मिलता है 12:01 जो 12:00 से अलग है। यदि यह आपके प्रकार के लिए एक तार्किक स्थिति है (अच्छा वैचारिक उदाहरण जो .NET में निर्मित नहीं हैं, तो पैसे, दूरी, वजन और UOM की अन्य मात्राएं हैं जहां संचालन को मूल्य के सभी भागों को ध्यान में रखना चाहिए) फिर एक संरचना का उपयोग करें और तदनुसार डिजाइन करें। अधिकांश अन्य मामलों में जहां किसी वस्तु के उप-आइटम स्वतंत्र रूप से परस्पर योग्य होने चाहिए, एक वर्ग का उपयोग करें।