c# - सूची क्यों रिफ के साथ पारित की तरह एक समारोह के लिए रेफरी बिना पारित कर दिया है?




c#-4.0 argument-passing (5)

अगर मुझे यह बहुत ग़लत नहीं मिला, तो यह व्यवहार मेरे लिए अजीब है समझाए जाने के बजाय, मैं नीचे एक नमूना कोड पोस्ट करूँगा और कृपया मुझे बताएं कि मुझे एक्सपी और एक्स से क्यों नहीं मिलता।

    private void button1_Click(object sender, EventArgs e)
    {
        List<int> l = new List<int>() { 1, 2, 3 };
        Fuss(l);
        MessageBox.Show(l.Count.ToString());
    }

    private void Fuss(List<int> l)
    {
        l.Add(4);
        l.Add(5);
    }

आउटपुट होना चाहिए, मुझे लगता है कि 3 होगा। लेकिन मुझे आउटपुट 5 जैसा मिलता है। मुझे लगता है कि आउटपुट 5 हो सकता है यदि मैं ऐसा करता हूं:

    private void button1_Click(object sender, EventArgs e)
    {
        List<int> l = new List<int>() { 1, 2, 3 };
        Fuss(ref l);
        MessageBox.Show(l.Count.ToString());
    }

    private void Fuss(ref List<int> l)
    {
        l.Add(4);
        l.Add(5);
    }

ByRef और ByVal केवल प्रकार के प्रकार पर लागू होते हैं, संदर्भ प्रकारों के लिए नहीं, जो हमेशा पारित होते हैं जैसे कि वे "बायफ" थे

यदि आपको सूची को सावधानी से संशोधित करने की आवश्यकता है, तो ".toList ()" फ़ंक्शन का उपयोग करें, और आपको अपनी सूची का क्लोन मिलेगा

ध्यान रखें कि अगर आपकी सूची में संदर्भ प्रकार शामिल हैं, तो आपकी "नई" सूची में एक ही ऑब्जेक्ट के लिए पॉइंटर्स शामिल हैं, जो आपकी मूल सूची में था।


केवल आदिम प्रकार जैसे इंट, डबल इत्यादि मूल्य द्वारा पास किए जाते हैं।

कॉम्प्लेक्स प्रकार (जैसे सूची) संदर्भ के माध्यम से पारित हो जाती है (जो मूल्य से गुजर रहा है, सटीक होना)।


यह रेफरी द्वारा पारित की तरह कार्य नहीं करता है

void ChangeMe(List<int> list) {
  list = new List<int>();
  list.Add(10);
}
void ChangeMeReally(ref List<int> list) {
  list = new List<int>();
  list.Add(10);
}

कोशिश करो। क्या आप अंतर देख रहे हैं?

आप केवल सूची की सामग्री (या कोई संदर्भ प्रकार) को बदल सकते हैं यदि आप इसे बिना किसी रेफरी के पास करते हैं (क्योंकि जैसा कि दूसरों ने कहा है, आप ढेर पर ऑब्जेक्ट का संदर्भ पास कर रहे हैं और इस प्रकार "स्मृति" को बदलते हैं)

हालांकि आप "सूची" बदल नहीं सकते हैं, "सूची" एक वेरिएबल है जो प्रकार की ऑब्जेक्ट को सूचीबद्ध करता है। यदि आप संदर्भ से इसे पास करते हैं तो आप केवल "सूची" को बदल सकते हैं (इसे कहीं और बिंदु बनाने के लिए) आप संदर्भ की एक प्रति प्राप्त करते हैं, जो कि यदि बदल दिया गया है, तो इसे केवल आपकी विधि के भीतर देखा जा सकता है।


संदर्भ जैसे संदर्भ प्रकारों के रेफरी और गैर-रेफरी में अंतर यह नहीं है कि आप एक संदर्भ (जो हमेशा होता है) पास करते हैं, लेकिन यह संदर्भ परिवर्तित किया जा सकता है या नहीं। निम्न प्रयास करें

private void Fuss(ref List<int> l)
{
    l = new List<int> { 4, 5 };
}

और आप देखेंगे कि गिनती 2 है, क्योंकि फ़ंक्शन ने न केवल मूल सूची में हेरफेर किया बल्कि संदर्भ खुद ही किया था


एक चर, पैरामीटर या प्रकार "सूची" या किसी अन्य संदर्भ प्रकार के क्षेत्र में वास्तव में एक सूची (या किसी अन्य वर्ग की वस्तु) नहीं होती है। इसके बजाय, यह "ऑब्जेक्ट आईडी # 29115" जैसा कुछ भी धारण करेगा (निश्चित रूप से इस तरह की कोई वास्तविक स्ट्रिंग नहीं, लेकिन बिट्स का एक संयोजन जो कि इसका अनिवार्य रूप से अर्थ है)। अन्यथा, इस प्रणाली में ढेर वाले वस्तुओं का अनुक्रमित संग्रह होगा; अगर प्रकार सूची के कुछ वैरिएबल "ऑब्जेक्ट आईडी # 29115" रखता है, तो ऑब्जेक्ट # 29115 हीप में सूची का एक उदाहरण या कुछ प्रकार से व्युत्पन्न होगा।

यदि मायफ़ू प्रकार की सूची का एक चर है, तो 'मायफू। एड' ("जॉर्ज") जैसी एक कथन वास्तव में मायफू नहीं बदलेगी; इसके बजाय, इसका अर्थ है "माइफू में संग्रहीत ऑब्जेक्ट आईडी की जांच करना, और उसमें संग्रहीत ऑब्जेक्ट की" ऐड "विधि का आह्वान करना। अगर मायफू ने निष्पादित कथन के पहले" ऑब्जेक्ट आईडी # 1 9 33 "का आयोजन किया, तो यह बाद में ऐसा करना जारी रखेगा, लेकिन ऑब्जेक्ट आईडी # 1 9 33 में अपनी ऐड विधि लागू होगी (संभवतः उस ऑब्जेक्ट को बदलना होगा)। इसके विपरीत, "माइफू = माइबर" जैसी एक ब्योरे मायफू को एक ही ऑब्जेक्ट-आईडी को माइबर के रूप में बनाएगी, लेकिन वास्तव में ऑब्जेक्ट में कुछ भी नहीं करेंगे यदि मायबारा ने बयान से पहले "ऑब्जेक्ट आईडी # 59212" का आयोजन किया है, तो बयान के बाद, मायफू में "ऑब्जेक्ट आईडी # 59212" भी होगा। ऑब्जेक्ट आईडी # 1 9 33, और न ही ऑब्जेक्ट आईडी # 59212 पर कुछ भी नहीं हुआ होगा।





ref