2010-06-14 7 views
39

में संदर्भ द्वारा वस्तुओं को ऑब्जेक्ट्स और ऑब्जेक्ट्स की एक सूची पास करना मेरे पास एक प्रतिनिधि है जो किसी ऑब्जेक्ट को संशोधित करता है। मैं एक ऑब्जेक्ट को एक कॉलिंग विधि से प्रतिनिधि को पास करता हूं, हालांकि कॉलिंग विधि इन परिवर्तनों को नहीं उठाती है। यदि मैं ऑब्जेक्ट के रूप में List पास करता हूं तो वही कोड काम करता है।सी #

मैंने सोचा कि सभी वस्तुओं को संदर्भ द्वारा पारित किया गया था ताकि किसी भी संशोधन कॉलिंग विधि में दिखाई दे। क्या वो सही है?

मैं प्रतिनिधि को ref ऑब्जेक्ट पास करने के लिए अपना कोड संशोधित कर सकता हूं। लेकिन मैं सोच रहा हूं कि यह क्यों जरूरी है। या यह है?

public class Binder 
{ 
    protected delegate int MyBinder<T>(object reader, T myObject); 

    public void BindIt<T>(object reader, T myObject) 
    { 
     //m_binders is a hashtable of binder objects 
     MyBinder<T> binder = m_binders["test"] as MyBinder<T>; 
     int i = binder(reader, myObject); 
    } 
} 

public class MyObjectBinder 
{ 
    public MyObjectBinder() 
    { 
     m_delegates["test"] = new MyBinder<MyObject>(BindMyObject); 
    } 

    private int BindMyObject(object reader, MyObject obj) 
    { 
     obj = new MyObject 
     { 
      //update properties 
     }; 
     return 1; 
    } 
} 

///calling method in some other class 
public void CallingMethod() 
{ 
    MyObject obj = new MyObject(); 

    MyObjectBinder binder = new MyObjectBinder(); 
    binder.BindIt(myReader, obj); //don't worry about myReader 

    //obj should show reflected changes 
} 

अद्यतन:

मैं अब प्रतिनिधि को ref द्वारा वस्तुओं गुजर रहा जैसा कि मैंने BindMyObject के अंदर एक नई वस्तु instantiating कर रहा हूँ।

protected delegate int MyBinder<T>(object reader, ref T myObject); 
+1

मुझे एहसास है कि आप मूल नामों को छिपाने की कोशिश कर रहे हैं, लेकिन आपको इसे साफ़ करना होगा। 'कॉलिंग मोड' के अंदर 'माईबिंदर' निश्चित नहीं है, 'MyObjectBinder' का उपयोग नहीं किया जाता है ... क्या वे वही हैं? मैं केवल यह मानने की कोशिश कर सकता हूं, और मैं ऐसा नहीं करना चाहता ... – Randolpho

उत्तर

103

ऑब्जेक्ट संदर्भ द्वारा पारित नहीं किए जाते हैं। ऑब्जेक्ट्स बिल्कुल पास नहीं होते हैं।

डिफ़ॉल्ट रूप से, तर्क का मान मान द्वारा पारित किया जाता है - चाहे वह मान मान प्रकार मान या संदर्भ हो। यदि उस संदर्भ के माध्यम से कोई ऑब्जेक्ट संशोधित किया गया है, तो वह परिवर्तन कॉलिंग कोड पर भी दिखाई देगा।

आपके द्वारा मूल रूप से दिखाए गए कोड में ref का उपयोग करने का कोई कारण नहीं था। ref कीवर्ड का उपयोग तब किया जाता है जब आप एक ऐसी विधि चाहते हैं जो पैरामीटर (उदा। इसे पूरी तरह से एक अलग ऑब्जेक्ट को संदर्भित करने के लिए) को बदलती है और उस परिवर्तन को कॉलर को दिखाई दे।

अब, कोड में आप दिखाया है (मूल) आप केवल मिल गया है: इस तरह

private int BindMyObject(object reader, MyObject obj) 
{ 
    obj = new MyObject(); 
} 

या कोड:

private int BindMyObject(object reader, MyObject obj) 
{ 
    //make changes to obj in here 
} 

आप इस तरह कोड का मतलब क्या

private int BindMyObject(object reader, MyObject obj) 
{ 
    obj.SomeProperty = differentValue; 
} 

? यदि यह बाद वाला है, तो आपको ref की आवश्यकता नहीं है। यदि यह पूर्व है, तो आप करेंref की आवश्यकता है क्योंकि आप पैरामीटर को बदल रहे हैं, उस ऑब्जेक्ट में परिवर्तन नहीं कर रहे हैं जो मान को संदर्भित करता है। वास्तव में, यदि आप हैं तोobj के मान को बिना पढ़ने के मान को सेट करते हुए, आपको ref के बजाय out का उपयोग करना चाहिए।

यदि आप एक छोटा लेकिन पूरा प्रोग्राम दिखा सकते हैं जो आपकी समस्या का प्रदर्शन करता है, तो यह समझाने में बहुत आसान होगा कि क्या हो रहा है।

इस विषय को केवल कुछ अनुच्छेदों में न्याय करना मुश्किल है - इसलिए मुझे entire article about it मिल गया है, जो उम्मीद है कि चीजों को और अधिक स्पष्ट कर देगा।

+1

अद्यतन उत्तर के लिए धन्यवाद।हां, समस्या इसलिए थी क्योंकि BindMyObject में मैं एक नई वस्तु शुरू कर रहा था। बस यह खुद को डीबगिंग पाया। – David

+1

@ डेविड लिडल - आप अपने मूल विषय में परिवर्तित कोड को शामिल करना चाहते हैं, इस तरह लोग देखते हैं कि आप किस प्रकार उपयोग कर रहे हैं। तो मैं इसे आरईएफ का उपयोग करके समाप्त कर देता हूं क्योंकि आपका कोड एक नया myObject नया है? – JonH

+1

@ जोनएच: मैंने अपने उत्तर को थोड़ा स्पष्ट करने के लिए अभी संशोधित कर दिया है कि कोड बदल गया है :) –