2010-01-04 15 views
9

कक्षाओं में मूल्य प्रकार गुणों के संबंध में ढेर और ढेर पर क्या होता है, इस बारे में भ्रमित हो रहा हूं।किसी संपत्ति से मूल्य प्रकार लौटाना

मेरे समझ अब तक:

जब आप इस तरह की एक संरचना (मान प्रकार) के साथ एक वर्ग बनाने के लिए:

Foo fooObj = new Foo(); 
: तुम इतनी तरह एक वर्ग उदाहरण बनाते हैं

class Foo 
{ 
    private Bar _BarStruct; 
    public Bar BarStruct 
    { 
    get {return _BarStruct; } 
    set {_BarStruct = value; } 
    } 
} 

private struct Bar 
{ 
    public int Number; 
    Bar() 
    { 
    Number = 1; 
    } 
    Bar(int i) 
    { 
    Number = i; 
    } 
} 

ढेर और ढेर इस तरह दिखेगा:

https://i962.photobucket.com/albums/ae105/acardy/stackheap-1.jpg(https://i962.photobucket.com/albums/ae105/acardy/stackheap-1.jpg)

... जहां ढांचे में फू क्लास में बार संरचना को एम्बेड किया गया है। यह मुझे समझ में आता है, लेकिन जब हम फू ऑब्जेक्ट के भीतर, बारस्ट्रक्चर क्लास में नंबर पूर्णांक को संशोधित करने पर विचार करते हैं, तो मैं इसे खोना शुरू करता हूं। उदाहरण के लिए:

Foo fooObj = new Foo(); 
fooObj.BarStruct.Number = 1; 

के रूप में मैं समझता हूँ, इस ढेर, जिसका अर्थ है कि BarStruct के एक सदस्य की कोई भी परिवर्तन करने के लिए वस्तु के माध्यम से किया नहीं होगा, यही कारण है पर रहने के BarStruct की एक प्रति लौट जाना चाहिए उपरोक्त अंतिम पंक्ति एक त्रुटि देता है।

क्या यह अभी तक सही है?

यदि हां, तो मेरे सवाल है, कैसे एक काम इस जैसे आते हैं:

fooObj.BarStruct = new Bar(2); 

... वैध है और ढेर मूल्य बदलता है? निश्चित रूप से यह सिर्फ ढेर पर मूल्य बदल रहा है ?? इसके अलावा, (द्वारा और द्वारा) मुझे यह इतना भ्रमित लगता है कि आप मूल्य प्रकार पर नए उपयोग करने में सक्षम हैं। मेरे लिए, ढेर पर आवंटन के लिए नया है (सी ++ के अनुसार) और ढेर पर वस्तुओं के लिए ऐसा करने के लिए अप्राकृतिक लगता है।

तो बस प्रश्न को दोबारा शुरू करने के लिए, क्या मैं अपनी धारणा में सही हूं कि एक संरचना वाली संपत्ति कहलाती है और आप एक प्रतिलिपि में एक नई संरचना क्यों निर्दिष्ट कर सकते हैं और फिर भी यह अभी भी संदर्भ को बदलता है ढेर?

वास्तव में उम्मीद है कि यह सब समझ में आता है।

येल अगर आपको स्पष्टीकरण की आवश्यकता है!

ता,

एंडी।

+0

@ एंडी, +1 अच्छा सवाल है। अगर आप 10 अनुभवी सी # प्रोग्रामर से पूछें तो मैं शर्त लगाऊंगा, आधा से भी कम पता चल जाएगा कि वास्तव में क्या हो रहा है। संरचनाएं मुश्किल हैं क्योंकि वे कक्षाओं की तरह दिखती हैं लेकिन उनके पास महत्वपूर्ण अंतर हैं। – Ash

उत्तर

10

इस असाइनमेंट को देखते हुए:

fooObj.BarStruct = new Bar(2); 

काम स्टैक पर मान बदलने नहीं है - यह संपत्ति के लिए सेटर कॉल कर रहा है।

दूसरे शब्दों में, जबकि अपना पहला काम के बराबर है:

fooObj.set_BarStruct(new Bar(2)); 

कि मदद करता है:

fooObj.get_BarStruct().Number = 1; // Bad 

दूसरे के बराबर है?

ध्यान दें कि यदि आप अपना मूल्य प्रकार शुरू करने के लिए अपरिवर्तनीय बनाते हैं तो समस्याग्रस्त असाइनमेंट एक गैर-मुद्दा बन जाता है - जो वास्तव में, वास्तव में मदद करता है। परिवर्तनीय मूल्य प्रकार सी # में वास्तव में एक बुरा विचार है; आप उनके साथ परेशानी का कोई अंत नहीं कर सकते हैं।

"नई" की आपकी अपेक्षाओं के संदर्भ में - मूल रूप से सी ++ में सोचने की कोशिश न करें। सी # सी ++ नहीं है, और विभिन्न चीजें (विनाशक, जेनेरिक, निर्माण के दौरान व्यवहार) आपको भ्रमित कर देगा यदि आप प्रभावी रूप से सी #+ को सी # में लिखने का प्रयास करते हैं। एक "नया" कथन एक प्रकार का एक नया उदाहरण बनाता है, चाहे वह एक मान प्रकार या संदर्भ प्रकार हो।

+0

असल में, इससे बहुत मदद मिलती है, वास्तव में मुझे यह सोचना चाहिए था कि यह थोड़ा और तर्कसंगत है, लेकिन उम्मीद है कि यह कुछ अन्य लोगों की भी मदद कर सकता है! :) बहुत बहुत धन्यवाद! – Andy

+0

जॉन, मुझे बस सिस्टम का उपयोग करके इस पर पकड़ा गया है। ड्रॉइंग। रेक्टंगल और सिस्टम। ड्रॉइंग.पॉइंट जब मैंने प्रोटीज़ में उन्हें लपेटने की कोशिश की। माइक्रोसॉफ्ट वास्तव में इन structs अपरिवर्तनीय बनाया जाना चाहिए था। – Ash

+0

@ एश: मैं सहमत हूं। उत्परिवर्तनीय structs एक * बहुत * प्रतिबंधित परिस्थितियों में उपयोगी हो सकता है, लेकिन वे फायदेमंद से लगभग हमेशा खतरनाक हैं। –

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