मुझे कक्षा के बजाय एक संरचना का उपयोग कब करना चाहिए?


303

MSDN का कहना है कि आपको हल्के वस्तुओं की आवश्यकता होने पर संरचनाओं का उपयोग करना चाहिए। क्या कोई अन्य परिदृश्य तब होता है जब कोई संरचना किसी वर्ग पर बेहतर होती है?

कुछ लोग भूल गए होंगे कि:

  1. संरचनाओं में विधियाँ हो सकती हैं।
  2. संरचनाएं विरासत में नहीं मिल सकती हैं।

मैं structs और वर्गों के बीच तकनीकी अंतर को समझने, मैं सिर्फ के लिए एक अच्छा लग रहा है की जरूरत नहीं है जब एक struct उपयोग करने के लिए।


बस एक अनुस्मारक - ज्यादातर लोग इस संदर्भ में क्या भूल जाते हैं कि सी # संरचनाओं में भी तरीके हो सकते हैं।
पेट्र के।

जवाबों:


296

MSDN का उत्तर है: कक्षाओं और संरचनाओं के बीच चयन

मूल रूप से, वह पृष्ठ आपको एक 4-आइटम चेकलिस्ट देता है और एक वर्ग का उपयोग करने के लिए कहता है जब तक कि आपका प्रकार सभी मानदंडों को पूरा नहीं करता है।

किसी संरचना को तब तक परिभाषित न करें जब तक कि सभी प्रकार में निम्नलिखित विशेषताएं न हों:

  • यह तार्किक रूप से आदिम प्रकार (पूर्णांक, डबल, और इसी तरह) के समान एकल मूल्य का प्रतिनिधित्व करता है।
  • इसका एक उदाहरण आकार 16 बाइट्स से छोटा है।
  • यह अपरिवर्तनीय है।
  • इसे बार-बार बॉक्सिंग नहीं करना पड़ेगा।

1
शायद मुझे कुछ स्पष्ट याद आ रहा है, लेकिन मुझे "अपरिवर्तनीय" भाग के पीछे तर्क नहीं मिला। यह क्यों आवश्यक है? क्या कोई इसे समझा सकता है?
तमस Czinege

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

@DrJokepu: कुछ स्थितियों में, सिस्टम एक संरचना की एक अस्थायी प्रतिलिपि बना देगा और फिर उस कॉपी को कोड के संदर्भ में पारित करने की अनुमति देगा जो इसे बदलता है; चूँकि अस्थायी प्रतिलिपि को जेल कर दिया जाएगा, इसलिए बदलाव खो जाएगा। यह समस्या विशेष रूप से गंभीर है यदि किसी संरचना में ऐसे तरीके हैं जो इसे म्यूट करते हैं। मैं दृढ़ता से इस धारणा से असहमत हूं कि उत्परिवर्तन एक वर्ग को कुछ बनाने का एक कारण है, क्योंकि - सी # और vb.net में कुछ कमियों के बावजूद, उत्परिवर्तनीय संरचना उपयोगी शब्दार्थ प्रदान करती है जिसे किसी अन्य तरीके से प्राप्त नहीं किया जा सकता है; एक वर्ग के लिए एक अपरिवर्तनीय संरचना को प्राथमिकता देने का कोई अर्थपूर्ण कारण नहीं है।
सुपरकैट

4
@Chuu: JIT कंपाइलर को डिजाइन करने में, Microsoft ने उन प्रतिरूपों की प्रतिलिपि बनाने के लिए कोड का अनुकूलन करने का निर्णय लिया जो 16 बाइट्स या छोटे हैं; इसका मतलब यह है कि 17-बाइट संरचना की नकल करना 16-बाइट संरचना की नकल करने की तुलना में काफी धीमा हो सकता है। मैं Microsoft से अपेक्षा करता हूं कि इस तरह के अनुकूलन को बड़ी संरचनाओं में विस्तारित करने के लिए कोई विशेष कारण नहीं है, लेकिन यह ध्यान रखना महत्वपूर्ण है कि जबकि 17-बाइट संरचनाएं 16-बाइट संरचनाओं की तुलना में धीमी हो सकती हैं, ऐसे कई मामले हैं जहां बड़ी संरचनाएं अधिक कुशल हो सकती हैं बड़े वर्ग की वस्तुएं, और जहां संरचना के सापेक्ष लाभ संरचना के आकार के साथ बढ़ता है
सुपरकैट

3
@Chuu: बड़ी संरचनाओं के समान उपयोग पैटर्न को लागू करने के लिए कक्षाओं में एक को अयोग्य कोड के परिणामस्वरूप रखा जाएगा, लेकिन उचित समाधान अक्सर कक्षाओं के साथ संरचनाओं को बदलने के लिए नहीं होता है, बल्कि इसके बजाय अधिक कुशलता से संरचनाओं का उपयोग करने के लिए; सबसे विशेष रूप से, किसी को मूल्य से संरचना को पारित करने या लौटने से बचना चाहिए। refजब भी ऐसा करना उचित हो तो उन्हें मापदंडों के रूप में पास करें। एक विधि के रेफरी पैरामीटर के रूप में 4,000 क्षेत्रों के साथ एक संरचना को पास करें, जो एक को बदलता है एक विधि के लिए 4 क्षेत्रों के साथ एक संरचना को पारित करने की तुलना में सस्ता होगा जो एक संशोधित संस्करण देता है।
सुपरकैट

54

मुझे आश्चर्य है कि मैंने पिछले उत्तर के किसी भी बिंदु पर नहीं पढ़ा है, जिसे मैं सबसे महत्वपूर्ण पहलू मानता हूं:

जब मैं कोई पहचान नहीं के साथ एक प्रकार चाहते हैं मैं संरचनाओं का उपयोग करें। उदाहरण के लिए एक 3D बिंदु:

public struct ThreeDimensionalPoint
{
    public readonly int X, Y, Z;
    public ThreeDimensionalPoint(int x, int y, int z)
    {
        this.X = x;
        this.Y = y;
        this.Z = z;
    }

    public override string ToString()
    {
        return "(X=" + this.X + ", Y=" + this.Y + ", Z=" + this.Z + ")";
    }

    public override int GetHashCode()
    {
        return (this.X + 2) ^ (this.Y + 2) ^ (this.Z + 2);
    }

    public override bool Equals(object obj)
    {
        if (!(obj is ThreeDimensionalPoint))
            return false;
        ThreeDimensionalPoint other = (ThreeDimensionalPoint)obj;
        return this == other;
    }

    public static bool operator ==(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2)
    {
        return p1.X == p2.X && p1.Y == p2.Y && p1.Z == p2.Z;
    }

    public static bool operator !=(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2)
    {
        return !(p1 == p2);
    }
}

यदि आपके पास इस संरचना के दो उदाहरण हैं, तो आप परवाह नहीं करते हैं कि वे स्मृति में डेटा का एक टुकड़ा है या दो। आप केवल उनके मूल्य के बारे में परवाह करते हैं।


4
विषय से थोड़ा हटकर, लेकिन जब आप थ्रीडिमेन्मेंट्रॉप्ट नहीं करते हैं तो आप एक ArgumentException को क्यों फेंकते हैं? क्या आपको उस मामले में गलत नहीं लौटना चाहिए?
Svish

4
यह सही है, मैं अत्यधिक उत्सुक था। return falseअभी जो कुछ होना चाहिए था, वह है।
आंद्रेई रैनिया

एक संरचना का उपयोग करने का एक दिलचस्प कारण। मैंने GetHashCode और Equals के साथ कक्षाएं बनाई हैं, जो आपके द्वारा यहां दिखाए गए समान के रूप में परिभाषित की गई हैं, लेकिन तब मुझे हमेशा उन उदाहरणों को म्यूट करने के लिए सावधान नहीं रहना पड़ता था यदि मैंने उन्हें शब्दकोश कुंजियों के रूप में उपयोग किया था। संभवत: सुरक्षित हो जाता अगर मैं उन्हें संरचना के रूप में परिभाषित करता। (क्योंकि तब कुंजी फ़ील्ड की एक प्रति होगी जिस समय संरचना एक शब्दकोश कुंजी बन गई थी , इसलिए यदि बाद में मैंने मूल बदल दिया तो कुंजी अपरिवर्तित रहेगी।)
टूलमेकरसेव

आपके उदाहरण में यह ठीक है क्योंकि आपके पास केवल 12 बाइट्स हैं, लेकिन ध्यान रखें कि यदि आपके पास उस संरचना में बहुत सारे फ़ील्ड हैं जो 16 बाइट्स को पार कर जाते हैं, तो आपको एक क्लास का उपयोग करने और गेटहैशकोड और समान विधियों को ओवरराइड करने पर विचार करना होगा।
डैनियल बोटेरो कोरे

डीडीडी में एक मूल्य प्रकार का मतलब यह नहीं है कि आपको सी # में एक मूल्य प्रकार का उपयोग करना चाहिए
दर्रागह

27

बिल वैगनर ने अपनी पुस्तक "प्रभावी सी #" ( http://www.amazon.com/Effective-Specific-Ways-Improve-Your/dp/0321245660 ) में इस बारे में एक अध्याय दिया है । वह निम्नलिखित सिद्धांत का उपयोग करके निष्कर्ष निकालता है:

  1. क्या टाइप डेटा स्टोरेज की मुख्य जिम्मेदारी है?
  2. क्या इसका सार्वजनिक इंटरफ़ेस पूरी तरह से गुणों से परिभाषित है जो अपने डेटा सदस्यों तक पहुंच या संशोधित करता है?
  3. क्या आप सुनिश्चित हैं कि आपके प्रकार में कभी उपवर्ग नहीं होंगे?
  4. क्या आप सुनिश्चित हैं कि आपके प्रकार का कभी बहुरूपता से व्यवहार नहीं किया जाएगा?

यदि आप सभी 4 प्रश्नों के लिए 'हां' का उत्तर देते हैं: एक संरचना का उपयोग करें। अन्यथा, एक वर्ग का उपयोग करें।


1
इसलिए ... डेटा ट्रांसफर ऑब्जेक्ट्स (DTO) को स्ट्रक्चर होना चाहिए?
क्रूजर

1
मैं कहूँगा हाँ, अगर यह ऊपर वर्णित 4 मानदंडों को पूरा करता है। डेटा ट्रांसफर ऑब्जेक्ट को एक विशिष्ट तरीके से इलाज करने की आवश्यकता क्यों होगी?
बार्ट गिजेन्सेंस

2
@ क्रूजर आपकी स्थिति पर निर्भर करता है। एक परियोजना पर, हमारे डीटीओ में सामान्य ऑडिट फ़ील्ड थे और इसलिए एक आधार डीटीओ लिखा, जो अन्य को विरासत में मिला।
एंड्रयू ग्रोटे

1
सभी (2) उत्कृष्ट सिद्धांतों की तरह प्रतीत होते हैं। यह जानने के लिए उसके तर्क को देखने की आवश्यकता होगी कि वह वास्तव में (2) से क्या मतलब है, और क्यों।
टूलमेकरसेव

1
@ टुल्मेकरसेव: आपको इसके लिए किताब पढ़नी होगी। यह मत सोचो कि किसी पुस्तक के बड़े हिस्से को कॉपी / पेस्ट करना उचित है।
बार्ट गिजेन्सेंस

15

जब आप संदर्भ-प्रकार के बजाय मान-प्रकार शब्दार्थ चाहते हैं तो एक संरचना का उपयोग करें। संरचनाएं कॉपी-बाय-वैल्यू हैं इसलिए सावधान रहें!

पिछले प्रश्न भी देखें, उदाहरण के लिए

.NET में संरचना और वर्ग के बीच अंतर क्या है?


11

जब मैं संरचना का उपयोग करूंगा:

  1. एक वस्तु को केवल पढ़ने के लिए माना जाता है (हर बार जब आप एक संरचना को पास / असाइन करते हैं तो यह कॉपी हो जाता है)। जब केवल बहुक्रियाशील प्रसंस्करण की बात आती है तो अधिकांश वस्तुएं महान होती हैं क्योंकि उन्हें अधिकांश मामलों में लॉकिंग की आवश्यकता नहीं होती है।

  2. एक वस्तु छोटी और छोटी होती है। ऐसे मामले में एक अच्छा मौका है कि ऑब्जेक्ट को स्टैक पर आवंटित किया जाएगा जो प्रबंधित ढेर पर डालने की तुलना में बहुत अधिक कुशल है। ऑब्जेक्ट द्वारा आवंटित की गई मेमोरी कितनी अधिक है, जैसे ही वह इसके दायरे से बाहर जाएगी, उसे मुक्त कर दिया जाएगा। दूसरे शब्दों में, यह गारबेज कलेक्टर के लिए कम काम है और मेमोरी का उपयोग अधिक कुशल है।


10

एक वर्ग का उपयोग करें यदि:

  • इसकी पहचान जरूरी है। एक विधि में मूल्य द्वारा पारित किए जाने पर संरचनाएं अंतर्निहित रूप से नकल हो जाती हैं।
  • इसमें एक बड़ा मेमोरी फुटप्रिंट होगा।
  • इसके खेतों को इनिशियलाइज़र की जरूरत है।
  • आपको बेस क्लास से विरासत में प्राप्त करने की आवश्यकता है।
  • आपको बहुरूपी व्यवहार की आवश्यकता है;

एक संरचना का उपयोग करें यदि:

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

5

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


4

यदि कोई इकाई अपरिवर्तनीय होने जा रही है, तो यह सवाल कि क्या एक संरचना या एक वर्ग का उपयोग करना आमतौर पर शब्दार्थ के बजाय प्रदर्शन में से एक होगा। 32/64-बिट सिस्टम पर, क्लास के संदर्भ में जानकारी की मात्रा की परवाह किए बिना, क्लास संदर्भों को स्टोर करने के लिए 4/8 बाइट्स की आवश्यकता होती है; क्लास रेफरेंस कॉपी करने के लिए 4/8 बाइट्स कॉपी करने होंगे। दूसरी ओर, हर अलगवर्ग उदाहरण के पास 8/16 बाइट्स होगी, इसके अतिरिक्त जानकारी और इसके संदर्भ की मेमोरी लागत। मान लीजिए कि 500 ​​संस्थाओं में से प्रत्येक को चार 32-बिट पूर्णांक रखने वाले एक सरणी चाहिए। यदि इकाई एक संरचना प्रकार है, तो सरणी को 8,000 बाइट्स की आवश्यकता होगी, भले ही सभी 500 इकाइयां सभी समान हों, सभी अलग हों, या कहीं बीच हों। यदि इकाई एक वर्ग प्रकार है, तो 500 संदर्भों की सरणी में 4,000 बाइट्स होंगे। यदि वे सभी संदर्भ अलग-अलग वस्तुओं को इंगित करते हैं, तो वस्तुओं को एक अतिरिक्त 24 बाइट्स की आवश्यकता होगी (सभी 500 के लिए 12,000 बाइट्स), कुल 16,000 बाइट्स - एक संरचनात्मक प्रकार की भंडारण लागत का दोगुना। दूसरी ओर, कोड ने एक ऑब्जेक्ट इंस्टेंस बनाया और फिर सभी 500 ऐरे स्लॉट्स के संदर्भ को कॉपी किया, कुल लागत उस उदाहरण और 4 के लिए 24 बाइट्स होगी; सरणी के लिए 000 - कुल 4,024 बाइट्स। एक बड़ी बचत। कुछ स्थितियों के साथ-साथ अंतिम एक भी काम करेगा, लेकिन कुछ मामलों में इस तरह के साझाकरण को सार्थक बनाने के लिए पर्याप्त सरणी स्लॉट्स के लिए कुछ संदर्भों को कॉपी करना संभव हो सकता है।

यदि इकाई को परिवर्तनशील माना जाता है, तो कक्षा या संरचना का उपयोग करने का प्रश्न कुछ तरीकों से आसान है। मान लें कि "थिंग" या तो एक संरचना या वर्ग है जिसमें एक पूर्णांक फ़ील्ड है जिसे x कहा जाता है, और एक निम्नलिखित कोड करता है:

  बात t1, t2;
  ...
  t2 = t1;
  t2.x = 5;

क्या कोई t1.x को प्रभावित करने के लिए बाद वाला बयान चाहता है?

यदि थिंग एक वर्ग प्रकार है, तो t1 और t2 समतुल्य होगा, जिसका अर्थ t1.x और t2.x भी समतुल्य होगा। इस प्रकार, दूसरा कथन t1.x को प्रभावित करेगा। यदि थिंग एक संरचना प्रकार है, तो t1 और t2 अलग-अलग उदाहरण होंगे, जिसका अर्थ t1.x और t2.x अलग-अलग पूर्णांकों को संदर्भित करेगा। इस प्रकार, दूसरा कथन t1.x को प्रभावित नहीं करेगा।

म्यूटेबल स्ट्रक्चर्स और म्यूटेबल क्लासेस में फंडामेंटल डिफरेंट बिहेवियर होते हैं, हालांकि .net में म्यूट स्ट्रक्चर म्यूटेशन से निपटने में कुछ क्वर्क होते हैं। यदि कोई मान-प्रकार का व्यवहार चाहता है (जिसका अर्थ है कि "t2 = t1" t1 और t2 को अलग-अलग उदाहरणों के रूप में छोड़ते हुए डेटा को t1 से t2 तक कॉपी करेगा), और यदि कोई .net में मूल्य प्रकारों की हैंडलिंग के साथ quirks के साथ रह सकता है, तो उपयोग करें। संरचना। यदि कोई मूल्य-प्रकार के शब्दार्थ चाहता है, लेकिन .net के प्रश्न एक आवेदन में टूटे हुए मूल्य-प्रकार के शब्दार्थ को जन्म देगा, तो कक्षा का उपयोग करें।


3

ऊपर उत्कृष्ट जवाब के अलावा:

संरचनाएं मूल्य प्रकार हैं।

वे करने के लिए कभी नहीं सेट किया जा सकता कुछ भी नहीं है

एक संरचना तय करना = कुछ भी नहीं, अपने सभी मूल्यों को उनके डिफ़ॉल्ट मूल्यों पर सेट करेगा।


2

जब आपको वास्तव में व्यवहार की आवश्यकता नहीं होती है, लेकिन आपको एक सरल सरणी या शब्दकोश की तुलना में अधिक संरचना की आवश्यकता होती है।

इस तरह से पालन ​​करें कि मैं कैसे सामान्य रूप से संरचनाओं के बारे में सोचता हूं। मुझे पता है कि उनके पास तरीके हो सकते हैं, लेकिन मैं उस समग्र मानसिक अंतर को बनाए रखना पसंद करता हूं।


तुमने ऐसा क्यों कहा? संरचनाओं में विधियाँ हो सकती हैं।
एस्टेबान अराया

2

जैसा कि @Simon ने कहा, संरचना "मूल्य-प्रकार" शब्दार्थ प्रदान करती है, इसलिए यदि आपको एक अंतर्निहित डेटा प्रकार के समान व्यवहार की आवश्यकता है, तो एक संरचना का उपयोग करें। चूंकि संरचनाएं प्रतिलिपि द्वारा पारित की जाती हैं आप यह सुनिश्चित करना चाहते हैं कि वे आकार में छोटे हैं, लगभग 16 बाइट्स।


2

यह एक पुराना विषय है, लेकिन एक साधारण बेंचमार्क टेस्ट देना चाहता है।

मैंने दो .cs फाइलें बनाई हैं:

public class TestClass
{
    public long ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

तथा

public struct TestStruct
{
    public long ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

बेंचमार्क चलाएँ:

  • 1 TestClass बनाएँ
  • 1 TestStruct बनाएँ
  • 100 TestClass बनाएँ
  • 100 TestStruct बनाएँ
  • 10000 TestClass बनाएँ
  • 10000 TestStruct बनाएँ

परिणाम:

BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18362
Intel Core i5-8250U CPU 1.60GHz (Kaby Lake R), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.1.101
[Host]     : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT  [AttachedDebugger]
DefaultJob : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT


|         Method |           Mean |         Error |        StdDev |     Ratio | RatioSD | Rank |    Gen 0 | Gen 1 | Gen 2 | Allocated |
|--------------- |---------------:|--------------:|--------------:|----------:|--------:|-----:|---------:|------:|------:|----------:|

|      UseStruct |      0.0000 ns |     0.0000 ns |     0.0000 ns |     0.000 |    0.00 |    1 |        - |     - |     - |         - |
|       UseClass |      8.1425 ns |     0.1873 ns |     0.1839 ns |     1.000 |    0.00 |    2 |   0.0127 |     - |     - |      40 B |
|   Use100Struct |     36.9359 ns |     0.4026 ns |     0.3569 ns |     4.548 |    0.12 |    3 |        - |     - |     - |         - |
|    Use100Class |    759.3495 ns |    14.8029 ns |    17.0471 ns |    93.144 |    3.24 |    4 |   1.2751 |     - |     - |    4000 B |
| Use10000Struct |  3,002.1976 ns |    25.4853 ns |    22.5920 ns |   369.664 |    8.91 |    5 |        - |     - |     - |         - |
|  Use10000Class | 76,529.2751 ns | 1,570.9425 ns | 2,667.5795 ns | 9,440.182 |  346.76 |    6 | 127.4414 |     - |     - |  400000 B |

1

हम्म ...

मैं क्लासेस बनाम कक्षाओं के उपयोग के खिलाफ / एक तर्क के रूप में कचरा संग्रह का उपयोग नहीं करूंगा। प्रबंधित हीप ढेर की तरह काम करता है - एक वस्तु का निर्माण बस इसे ढेर के शीर्ष पर रखता है, जो लगभग ढेर पर आवंटित करने के रूप में तेज़ है। इसके अतिरिक्त, यदि कोई वस्तु अल्पकालिक है और एक जीसी चक्र से नहीं बचती है, तो डीलक्लोकेशन मुफ्त है क्योंकि जीसी केवल मेमोरी के साथ काम करता है जो अभी भी सुलभ है। (खोज MSDN, .NET मेमोरी प्रबंधन पर लेखों की एक श्रृंखला है, मैं उनके लिए खुदाई करने के लिए बहुत आलसी हूं)।

अधिकांश समय मैं एक संरचना का उपयोग करता हूं, मैं ऐसा करने के लिए खुद को लात मारता हूं, क्योंकि मुझे बाद में पता चलता है कि संदर्भ शब्दार्थ होने से चीजें थोड़ी सरल हो जाती हैं।

वैसे भी, ऊपर पोस्ट किए गए MSDN लेख में वे चार बिंदु एक अच्छी दिशानिर्देश हैं।


1
यदि आपको कभी-कभी एक संरचना के साथ संदर्भ शब्दार्थ की आवश्यकता होती है, तो बस घोषित करें class MutableHolder<T> { public T Value; MutableHolder(T value) {Value = value;} }, और फिर एक MutableHolder<T>परिवर्तनशील वर्ग शब्दार्थ के साथ एक वस्तु होगी (यह काम करता है अगर Tएक संरचना या एक अपरिवर्तनीय वर्ग प्रकार है)।
सुपरकैट

1

संरचनाएँ ढेर पर नहीं हैं इसलिए वे सुरक्षित हैं, और उनका उपयोग तब किया जाना चाहिए जब स्थानांतरण ऑब्जेक्ट पैटर्न को लागू करते हैं, आप कभी भी उन वस्तुओं का उपयोग नहीं करना चाहते हैं, जो ढेर हैं वे अस्थिर हैं, आप इस मामले में कॉल स्टैक का उपयोग करना चाहते हैं। यह एक संरचना का उपयोग करने के लिए एक मूल मामला है, मैं यहां सभी उत्तरों से आश्चर्यचकित हूं,


-3

मुझे लगता है कि सबसे अच्छा जवाब बस संरचना का उपयोग करना है जब आपको आवश्यक गुणों का संग्रह होता है, तब जब यह गुणों और व्यवहारों का संग्रह होता है।


संरचनाओं में विधियाँ भी हो सकती हैं
नितिन चंद्रन

बेशक, लेकिन अगर आपको तरीकों की जरूरत है, तो संभावनाएं 99% हैं आप अनुचित तरीके से वर्ग के बजाय संरचना का उपयोग कर रहे हैं। केवल अपवाद मैंने पाया जब यह तरीकों में struct कॉलबैक हैं ठीक है
लुसियान गेब्रियल पोपेस्कु
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.