2015-11-21 9 views
5

मैं इस बारे में उत्सुक हूं कि सी # व्यवहार विधि/संदर्भ प्रकारों को किसी विधि में कब गुजरता है। मैं "AddThree" विधि में एक बॉक्स किए गए मान प्रकार को पास करना चाहता हूं। विचार "कॉलर फ़ंक्शन (मुख्य) में प्राप्त करना है" AddThree "के अंतर्गत किए गए संचालन का नतीजा।बॉक्सिंग मान प्रकार को किसी विधि को भेजने के लिए और परिणाम प्राप्त करें

static void Main(string[] args) 
{ 
    int age = 3; 
    object myBox = age; 
    AddThree(myBox); 
    // here myBox = 3 but I was expecting to be = 6 
} 

private static void AddThree(object age2) 
{ 
    age2 = (int)age2 + 3; 
} 

मैं स्ट्रिंग की तरह शुद्ध संदर्भ प्रकार के साथ इस की कोशिश की है और मैं एक ही परिणाम मिलता है। यदि मैं कक्षा में अपने int "लपेटता हूं" और मैं इस उदाहरण में "रैप" कक्षा का उपयोग करता हूं, जैसा कि मैं उम्मीद कर रहा हूं, यानी, मुझे myBox = 6. मिलता है। यदि मैं "AddThree" विधि हस्ताक्षर को संशोधित करने के लिए संशोधित करता हूं रेफरी द्वारा पैरामीटर, यह भी 6 देता है। लेकिन, मैं हस्ताक्षर को संशोधित नहीं करना चाहता हूं या रैपर वर्ग नहीं बनाना चाहता हूं, मैं सिर्फ मूल्य को बॉक्स करना चाहता हूं।

+0

हस्ताक्षर बदलने के बिना ऐसा करने का कोई तरीका नहीं है क्योंकि आपको 'आयु 2'' को 'ref' पैरामीटर होने की आवश्यकता है। – Lee

उत्तर

2

मैं हस्ताक्षर को संशोधित करने या एक आवरण वर्ग बनाने के लिए नहीं करना चाहते हैं, मैं सिर्फ मूल्य बॉक्स करना चाहते ।

फिर यह एक समस्या होगी। आपकी विधि int को बॉक्स किया गया है, फिर उसे अनबॉक्स करता है और स्थानीय age2 पर 3 जोड़ता है, जो एक और मुक्केबाजी ऑपरेशन का कारण बनता है, और उसके बाद मूल्य को फेंकता है। वास्तव में, आप age2 को ढेर पर दो अलग-अलग ऑब्जेक्ट्स पर assinging कर रहे हैं, वे एक ही वस्तु को इंगित नहीं करते हैं। विधि हस्ताक्षर को संशोधित किए बिना, यह संभव नहीं होगा।

आप AddThree के लिए उत्पन्न आईएल को देखें, तो आप स्पष्ट रूप से यह देखेंगे:

AddThree: 
IL_0000: nop   
IL_0001: ldarg.0  
IL_0002: unbox.any System.Int32 // unbox age2 
IL_0007: ldc.i4.3 // load 3 
IL_0008: add   // add the two together 
IL_0009: box   System.Int32 // box the result 
IL_000E: starg.s  00 
IL_0010: ret  

आप मूल्य Unbox, 3 जोड़ने और फिर मूल्य फिर से बॉक्स, लेकिन आप इसे वापस कभी नहीं।

इस मामले में आगे की कल्पना, विधि (सिर्फ परीक्षण के लिए) से नव बॉक्सिंग मूल्य लौटने की कोशिश, और object.ReferenceEquals का उपयोग उन दोनों की तुलना करने के लिए:

static void Main(string[] args) 
{ 
    int age = 3; 
    object myBox = age; 
    var otherBox = AddThree(myBox); 
    Console.WriteLine(object.ReferenceEquals(otherBox, myBox)); // False 
} 

private static object AddThree(object age2) 
{ 
    age2 = (int)age2 + 3; 
    return age2; 
} 
1

एक के लिए एक नया मान निर्दिष्ट ref द्वारा पारित विधि पैरामीटर मूल संदर्भ नहीं बदलेगा।

आपके मामले में, age2 (विधि पैरामीटर) myBox की एक प्रति है। वे दोनों एक ही ऑब्जेक्ट को संदर्भित करते हैं (बॉक्स), लेकिन age2 को असाइन करने से myBox नहीं बदला जाता है। यह बस age2 अन्य ऑब्जेक्ट को संदर्भित करता है।

वास्तव में, इसका मुक्केबाजी के साथ कुछ लेना देना नहीं है। यह सिर्फ विधियों को पैरामीटर कैसे पारित किया जाता है।

+0

यह मुक्केबाजी के बारे में है, अगर परम int होगा, रेफ यहां मदद करेगा। लेकिन मुक्केबाजी मूल int की अस्थायी प्रतिलिपि बनाता है, और इस प्रतिलिपि में संशोधन वैसे भी खो जाएगा और बिना किसी रेफरी के। – ISanych

+0

@ISanych ओपी 'मायबॉक्स' (बॉक्सिंग वाला) बदलना चाहता था, 'उम्र' ('int') नहीं: // // यहां मेरा बॉक्स = 3 लेकिन मैं = 6' होने की उम्मीद कर रहा था। पैरामीटर को 'रेफ ऑब्जेक्ट' के रूप में पास करना इसे पूरा करेगा। –

+0

आप सही हैं, मैंने भाग खो दिया है कि ओपी बॉक्सिंग मूल्य चाहता था। – ISanych

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