2010-09-20 25 views
8

शायद इसके लिए काफी तार्किक स्पष्टीकरण है, लेकिन मेरे पास एक प्रश्न है।एक चर और गुण को संशोधित करने के बीच अंतर

मान लें कि मेरे पास एक प्रकार का आयताकार है जिसे _rect कहा जाता है। अब मैं _rect.X = 50 कह सकता हूं; बिना किसी समस्या के।

अब मेरे पास रेक्ट नामक एक संपत्ति है जिसमें आंतरिक चर _ सही है।

तो फिर, अगर मैं Rect.X = 50; लिखने की कोशिश मैं निम्नलिखित संकलन त्रुटि मिलती है:

'TestClass.Rect' की वापसी मान संशोधित नहीं कर सकते, क्योंकि यह एक चर नहीं है।

मैं Rect = new Rectangle(50, Rect.Y, Rect.Width, Rect.Height) लिख सकता हूं एक अपरिवर्तनीय प्रकार के लिए, लेकिन गैर-अपरिवर्तनीय प्रकारों के लिए, क्या ऐसा करने का कोई और तरीका है?

मैं इस आयताकार क्षेत्र के लिए ऑटो-प्रॉपर्टी का उपयोग करना चाहता हूं, लेकिन यह वास्तव में कक्षा में ही इसे संशोधित करने में सक्षम नहीं है।

क्या बैकिंग फ़ील्ड बनाने और ऑटो-संपत्ति को छोड़ने से कोई रास्ता कम है?

+0

आप हमें रेक्ट वर्ग के लिए अपने कोड दिखा सकते हैं? और आप बिल्ट-इन रेक्ट क्लास का उपयोग क्यों नहीं करते? –

+0

आयताकार एक वर्ग या संरचना है? यदि यह एक संरचना है, तो इसे कक्षा – Rohith

+0

बनाने का प्रयास करें, हमें एक पूर्ण कोड सूची दें, मेरे लिए यह कहना मुश्किल है कि आप क्या कह रहे हैं और यह आपके प्रश्न को स्पष्ट करने में मदद करेगा। –

उत्तर

10

इस त्रुटि का कारण यह है क्योंकि Rectangle संदर्भ प्रकार (वर्ग) के विपरीत एक मान प्रकार (संरचना) है। आप X प्रॉपर्टी को संशोधित नहीं कर सकते हैं क्योंकि जब आप Rect प्रॉपर्टी गेटटर का उपयोग करते हैं तो आयताकार के लिए एक नया मान लौटाया जाता है (गेटटर एक फ़ंक्शन है)। यदि यह संदर्भ प्रकार था तो आप पॉइंटर में हेरफेर कर रहे हैं और यह संभव होगा।

यह मूल्य बनाम संदर्भ प्रकारों का एक महत्वपूर्ण पहलू है जिसके बारे में पता होना चाहिए।

+0

यह सुनिश्चित करने के लिए, कोई * तकनीकी * कारण नहीं है कि संकलक यह काम क्यों नहीं कर सका।कंपाइलर उपयोगकर्ता के लिए सभी प्रकार के अतिरिक्त कोड उत्पन्न करता है (जैसे मुक्केबाजी), तो यहां क्यों नहीं? (वास्तव में, कारण शायद यह माना जाता है कि यह महत्वपूर्ण नहीं माना जाता है क्योंकि structs को अपरिवर्तनीय होना चाहिए।) –

+0

@ कोनराड - परिणामस्वरूप पारित होने पर structs की प्रतिलिपि बनाई जाती है, इसलिए ऑपरेशन बस कोई समझ नहीं लेता है। यह अपरिवर्तनीयता के कारण नहीं है (structs mutable हैं)। लेकिन अगर आप किसी ऑब्जेक्ट की एक प्रति पुनर्प्राप्त करते हैं और उस प्रतिलिपि में फ़ील्ड को बदलते हैं - यह बस एक एनओयूपी है। – viraptor

+0

@viraptor: मैं असहमत हूं। ऑपरेशन स्पष्ट रूप से समझ में आता है: एक संपत्ति को बदलना। संकलक आसानी से 'var tmp = foo.Property' के बराबर कोड उत्पन्न करके यह काम कर सकता है; tmp.x = newX; foo.Property = tmp; '- कंपाइलर वास्तव में ** यह समकक्ष स्थिति के लिए ** करता है: जब आपके पास मूल्य प्रकार की संपत्ति होती है और 'foo.Property + = 1' लिखती है ** यह ** काम करती है ** (मोनो कंपाइलर पर परीक्षण)। कंपाइलर स्पष्ट रूप से उपरोक्त कोड को फिर से लिखता है। –

1

संपत्ति तक पहुंच वास्तव में एक फ़ंक्शन कॉल है जो मान प्रकार की एक प्रति लौटाती है। Rect.X = 50; केवल इस अस्थायी प्रति को संशोधित करेगा, न कि बैकिंग फ़ील्ड।

जब संपत्ति स्वत: लागू नहीं होती है, तो आप एक अतिरिक्त संपत्ति RectX बना सकते हैं, जिसका उपयोग आयताकार की एक्स प्रॉपर्टी को प्राप्त करने और सेट करने के लिए किया जा सकता है।

+0

मुझे समझ में नहीं आता है, अब मुझे बेवकूफ बेवकूफ लगता है नया आयताकार (...) क्यों काम करता है, और Rect.X = 50 नहीं, क्योंकि दोनों प्रतिलिपि पर काम करते थे, लेकिन जब मैं नया आयताकार लिखता हूं तो मैं सेट के बजाय सेट को कॉल कर रहा हूं। इसके बारे में अपना खुद का सिर स्पष्ट करने के लिए धन्यवाद। तो इसका मूल रूप से मतलब नहीं है। अगर मैं उस तरह के व्यवहार चाहता हूं, तो मुझे बैकिंग फ़ील्ड का उपयोग करना होगा। –

+0

बैकिंग फ़ील्ड का उपयोग करते समय व्यवहार अभी भी वही होगा, गेटर और सेटर विधियां जारी रहेंगे, फिर भी आपको आयताकार उदाहरण की एक वैल्यू कॉपी मिल जाएगी। जो व्यवहार आप चाहते हैं वह केवल संदर्भ प्रकारों के लिए है, क्योंकि तब आपको मूल ऑब्जेक्ट उदाहरण के लिए "संदर्भ" मिलता है। हालांकि आयताकार एक वैल्यू प्रकार है। –

0
class RectangleWithoutFields 
    { 
    // just autoproperties, no fields 

    public int X { get; set; } 

    public int Y { get; set;} 


    public RectangleWithoutFields() 
    { 
     X = 0; 

     Y = 0; 
    } 

    public void ChangeProperties(int x, int y) 

    { 
     X = x; 

     Y = y; 
    } 
} 
+0

मैं नहीं था यहां एक नया आयताकार बनाने की कोशिश कर रहा है, लेकिन इसे मानक आयताकार के साथ काम करने के लिए :) –

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