2011-04-06 6 views
6

मैं हाल ही में CancellationToken संरचना के आंतरिक में देख रहा था और थोड़ा अजीब निर्माण (अधिक सटीक होने के लिए, this कीवर्ड के लिए मूल्य असाइनमेंट) की खोज की।इस कीवर्ड के लिए संरचना मूल्य का असाइनमेंट

public CancellationToken(bool canceled) 
{ 
    this = new CancellationToken(); 
    if (canceled) 
    { 
     this.m_source = CancellationTokenSource.InternalGetStaticSource(canceled); 
    } 
} 

लाइन this कीवर्ड को काम होता है, जिस पर का अर्थ क्या है:

इसके निर्माताओं में से एक संहिता निम्नलिखित के रूप में है?

कृपया ध्यान दें कि कक्षाओं के लिए this कीवर्ड असाइनमेंट संभव नहीं है - त्रुटि Cannot assign to '<this>' because it is read-only होती है।

उत्तर

6

यह सी # की एक बहुत ही कम ज्ञात विशेषता है - यह एक संरचना को अपने डेटा को ओवरराइट करने की अनुमति देता है। मुझे यकीन नहीं है कि यह केवल ब्लिटेबल वैल्यू प्रकारों के लिए उपलब्ध है या नहीं (मुझे अनुमान नहीं है)।

जहां तक ​​व्यावहारिक अनुप्रयोग चला जाता है, तो आप इस के लिए कई उपयोगों को खोजने के लिए नहीं जा रहे हैं ..

struct MyStruct 
{ 
    int a = 1; 
    int b = 2; 
    int c = 3; 

    public void Mutate() 
    { 
     a = 10; 
     b = 20; 
     c = 30; 
    } 

    public void Reset() 
    { 
     a = 1; 
     b = 2; 
     c = 3; 
    } 

    public void Reset2() 
    { 
     this = new MyStruct(); 
    } 

    // The two Reset methods are equivilent... 
} 

इसके बारे में अधिक सोच रही थी, वहाँ में एक मौलिक अंतर क्या "इस" का अर्थ है जब आप कर रहे हैं मूल्य प्रकार बनाम संदर्भ प्रकार से निपटना।

जब आप किसी संदर्भ प्रकार पर "यह" कहते हैं - जो आपको मिलता है वह एक पॉइंटर होता है जो ढेर पर रहता है, तो आप वास्तव में वस्तु को स्वयं नहीं प्राप्त करते हैं। पॉइंटर पूरी तरह से ढेर पर वस्तु को वापस संदर्भित करता है, जो संकेतों को सारणीबद्ध करता है। अब अगर आप ने कहा की तरह कुछ इस = नए MyReferenceType(), आप वर्तमान क्षेत्रमें सूचक एक अलग ढेर वस्तु को इंगित करने के लिए बदल गया है - आप नहीं ढेर में मूल वस्तु में कोई बदलाव नहीं है, और न ही कोई अन्य संदर्भ/पॉइंटर्स अब नए ढेर ऑब्जेक्ट का संदर्भ लें। इसकी बहुत संभावना है कि जैसे ही आपका उत्परिवर्तित पॉइंटर गुंजाइश से बाहर हो गया - आपके द्वारा बनाई गई नई ढेर वस्तु कचरा संग्रह के अधीन होगी।

जब आप किसी मान प्रकार पर "यह" कहते हैं - आपको वास्तविक वस्तु मिल रही है, संदर्भ या सूचक नहीं। कोई संकेत नहीं है, इसलिए आप इस स्मृति स्थान पर कच्चे बिट्स को ओवरराइट करने के लिए स्वतंत्र हैं (जो डिफ़ॉल्ट कन्स्ट्रक्टर करता है)।

1

बस एक अनुमान:

हर वर्ग के लिए एक संदर्भ प्रकार अर्थ है कि स्मृति ढेर में आवंटित किया जाता है और फोन करने वाले सूचक के माध्यम से वास्तविक डेटा के लिए उपयोग हो जाता है। उदाहरण के लिए:

Customer c1 = new Customer('CUSTID'); // "Customer" is a reference type 
Customer c2 = c1; // "c1" and "c2" points to the same memory within the heap 

हर struct एक मान प्रकार अर्थ है कि स्मृति ढेर में आवंटित किया जाता है और फोन करने वाले वास्तविक उदाहरण के साथ के बजाय कि उदाहरण के संदर्भ में संबंधित है।उदाहरण के लिए:

Customer c1 = new Customer('CUSTID'); // "Customer" is a value type 
Customer c2 = c1; // New memory gets allocated for "c2" within the stack 

अपने उदाहरण को ध्यान में रखते: एक struct पर निम्नलिखित कार्यवाही संचालित करने

this = new Customer(); 

बस शून्य मूल्यों के साथ यह initializes:

mov eax,dword ptr [ebp-3Ch] ; Save pointer to "ebp-3Ch" in EAX register 
xor edx,edx     ; Clear EDX register 
mov dword ptr [eax],edx  ; Write "zero" by address containing in EAX 

मैं क्यों यह नहीं है पता नहीं है संदर्भ प्रकारों के साथ संभव है लेकिन मेरा अनुमान है कि पूरे ऑब्जेक्ट ग्राफ़ को पूरी तरह से "रीसेट" करने की आवश्यकता होगी (जो एक आसान काम नहीं हो सकता है)। मुझे लगता है कि परिपत्र संदर्भों के मामले में यह मूल्यवान हो जाएगा।

फिर, यह सिर्फ मेरे विचार है और मैं किसी को भी साबित करने या त्यागने के लिए बहुत पसंद करता हूं (निश्चित रूप से, स्पष्टीकरण के साथ)।

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