2011-03-10 16 views
7

में कन्स्ट्रक्टर से रेफ पैरामीटर रखें मूल रूप से मैं कक्षा के उदाहरण के अंदर एक चर के संदर्भ में सक्षम होना चाहता हूं, लेकिन मैं संदर्भ वर्ग बनने के संदर्भ को संदर्भित करना चाहता हूं इसलिए मुझे इसकी आवश्यकता नहीं है पैरामीटर के रूप में कक्षा के अंदर चारों ओर इसे भेजनेसी #: कक्षा

कोड:

int num = 0; 
myClass(num); 
print num; // output is 0 but i'd like it to be 10 :) 
class myClass 
{ 
    private int classNumber; 
    myClass(ref int number) 
    { 
     print number; //output is 0 

     // id like this to be a reference to the refenrence 
     classNumber = number; 

     DoSomething(); 
    } 
    public void DoSomething() 
    { 
     ClassNumber = 10; 
    } 
} 

मैं यही कारण है कि पूछ रहा हूँ क्योंकि मैं WinForms के साथ काम कर रहा हूँ और एक नया करने के लिए एक वर्ग का एक उदाहरण भेजने के एक मुख्य रूप होने फॉर्म जो कक्षा को संपादित करना चाहिए और उसे वापस भेजना चाहिए .. अभी मैं फॉर्म को .ShowDialog() का उपयोग करता हूं ताकि उपयोगकर्ता को नए रूप में संपादन करते समय मुख्य रूप का उपयोग करने से बचें और उस हथियाने के बाद नए फॉर्मों का डेटा

editForm edtfrm = new editForm(ref instanceOfClass); 
edtfrm.showDialog(); 
//grab the instance back 
instanceOfClass = edtfrm.editedClass; 

मैं इसे कैसे हल कर सकता हूं? मुझे यह समाधान पसंद नहीं है

+0

आपका दोनों समस्याओं पूरी तरह से असंबंधित लग रहे हैं। क्या आप सुनिश्चित हैं कि समस्या 1 का समाधान आपको समस्या 2 हल करने में मदद करेगा? – Heinzi

+0

"समस्या 2" बस मैं इस दुविधा को कैसे हल करता हूं .. मैं जो संदर्भ देता हूं उसकी प्रतिलिपि बनाकर और फिर जब मैं इसे संपादित कर रहा हूं तो इसे वापस कॉपी कर रहा हूं, समस्या 1 में अगर मैंने "कक्षा संख्या" सार्वजनिक और प्रिंट से पहले किया मैं 'num = myClass.classNumber' – Tistatos

+2

करूँगा क्योंकि 'instanceOfClass' एक संदर्भ है, इसलिए आपको इसे पास करने के लिए' ref' का उपयोग करने की आवश्यकता नहीं है (क्योंकि आप' instanceOfClass' की * सामग्री * को बदलना चाहते हैं, पॉइंटर नहीं अपने आप)। मैं यह भी नहीं देखता कि आपको "उदाहरण वापस लेना" क्यों है ... exampleOfClass और संपादित क्लास अभी भी स्मृति में एक ही ऑब्जेक्ट को इंगित करना चाहिए, नहीं? – Heinzi

उत्तर

0

एक संपत्ति के रूप में अपना नंबर रखने वाली कक्षा बनाएं और इसे अपने तर्क में पारित करें। वह वर्ग आपके "मॉडल" का प्रतिनिधित्व करेगी।

0

आप ref पैरामीटर को सहेज नहीं सकते हैं, ref कोई संदर्भ नहीं है, यह केवल alias है। यदि आपके पास:

public void Stuff (ref int i) 
{ 
    i = 2; 
} 

और यह कहते हैं:

int s = 1; 
Stuff(ref s); 

ref का अर्थ है "मैं s के लिए एक उपनाम बनाने के लिए और यह करने के लिए परिवर्तन को प्रचारित"। एक बार जब आप विधि का दायरा छोड़ देते हैं, तो उपनाम समाप्त हो जाता है। संयोग से, एरिक लिपर्ट ने अपने blog पर एक श्रृंखला शुरू की।

आपको कक्षा बनाना चाहिए और अपने तर्क में इसका उपयोग करना चाहिए। जीयूआई को मूल्यों में हेरफेर नहीं करना चाहिए, केवल बैकएंड चाहिए।

0

यहां चीज़ों का जोड़ा। पहले, अपने निर्माता में आप शायद चाहते

DoSomething();  
number=classnumber; 
बजाय

classnumber=number; 

दूसरा करते हैं, की कोशिश करो

myClass(ref num); 
बजाय

myClass(num); 
+0

मैंने पोस्ट में 'रेफरी' जोड़ा;)। जो कि मैंने समस्या प्रस्तुत करने के तरीके के लिए काम कर सकता है।हालांकि मेरी समस्या एक Winforms के भीतर निहित है, इसलिए मैं कन्स्ट्रक्टर के भीतर सभी संपादन नहीं कर सकता जैसा मैंने किया था। क्योंकि नया रूप किसी अन्य धागे में है और मुझे उस संदर्भ को नए रूप में जीवंत रखने की आवश्यकता है – Tistatos

2

यह वास्तव में एक अच्छा नहीं है विचार क्या y ,

public class ClassContructorReference 
{ 
    static void Main(string[] args) 
    { 
     object var = new object(); 
     MyClass myClass = new MyClass(var); 
     StringBuilder mySb = myClass.Instance as StringBuilder; 
     Console.WriteLine(mySb.ToString()); 
    } 
} 

public class MyClass 
{ 
    public object Instance {get;set;} 

    public MyClass(object var) 
    { 
     this.Instance = var; 
     DoSomething(); 
    } 

    private void DoSomething() 
    { 
     this.Instance = new StringBuilder("Hello"); 
    } 
} 
14

मैं एक वर्ग का एक उदाहरण के अंदर एक चर के लिए एक संदर्भ के लिए सक्षम होना चाहते हैं: कहां मैं नीचे की तरह वर्ग के एक संपत्ति के रूप में संशोधित वस्तु का पर्दाफाश होगा करने के लिए कोशिश कर रहे हैं, लेकिन मैं क्लास वैरिएबल बनने के संदर्भ को संदर्भित करना चाहता हूं इसलिए मुझे इसे कक्षा के अंदर भेजने के लिए पैरामीटर

आपको निराशा के साथ रहना होगा। सीएलआर प्रकार प्रणाली कक्षाओं के सदस्यों के रूप में चर के संदर्भों के भंडारण को स्पष्ट रूप से प्रतिबंधित करती है।CLR

  • औपचारिक पैरामीटर या करने के लिए इसी तर्क के रूप में तरीकों को पारित कर दिया 'इस'
  • स्थानीय लोगों
  • विधि वापसी के रूप में वापस के रूप में जमा होने के लिए चर के लिए संदर्भ परमिट को महत्व देता

लेकिन करता है सरणी, फ़ील्ड आदि में भंडारण की अनुमति नहीं है। असल में, "ढेर पर" जो कुछ भी जाता है वह एक रेफरी पर नहीं पकड़ सकता है।

सी # पहली सुविधा का खुलासा करता है: विधि पैरामीटर के रूप में चर के लिए refs। यह अन्य दो विशेषताओं का खुलासा नहीं करता है (हालांकि मैंने सी # का एक प्रयोगात्मक संस्करण लिखा है, और यह काफी अच्छी तरह से काम करता है।)

ध्यान दें कि सी # आपको संदर्भों में रेफरी का उपयोग करने की अनुमति नहीं देता है जिसके लिए ढेर भंडारण की आवश्यकता होगी उदाहरण के लिए, एक लैम्ब्डा के बंद-ओवर बाहरी चर होने के रूप में रेफरी पैरामीटर की तरह रेफरी। कुछ दुर्लभ मामले हैं जिनमें संकलक रेफरी के दीर्घकालिक भंडारण की तरह दिखता है, और रेफरी अनुकरण करने के लिए कॉपी-इन-कॉपी-आउट सेमेन्टिक्स का उपयोग करता है, लेकिन शायद वहां तक ​​जाने के लिए सबसे अच्छा नहीं है।

सीएलआर के पास यह प्रतिबंध क्यों है? इसके बारे में सोचने का सही तरीका यह है कि दो प्रकार के भंडारण होते हैं: दीर्घकालिक और अल्पकालिक, जिसे आमतौर पर "ढेर" और "ढेर" कहा जाता है। लेकिन डेटा संरचना का आकार अप्रासंगिक है; जीवनकाल की लंबाई प्रासंगिक क्या है। एक चर के भंडारण स्थान है; यही एक चर है। यदि आप लंबी अवधि के भंडारण में शॉर्ट-टर्म स्टोरेज से आवंटित चर के लिए एक रेफरी रख सकते हैं तो दीर्घकालिक भंडारण कम जीवनकाल की तरह कुछ रिफ्रेश रखता है, और इसलिए जब यह चर का उपयोग करता है तो क्रैश और मर सकता है इसकी मृत्यु के बाद।

जाहिर है इस समस्या को हल करने के कई तरीके हैं। उदाहरण के लिए, सीएलआर टीम शॉर्ट टर्म स्टोरेज को रिफ्रेश करने के लिए अवैध बनाने के लिए चुना जा सकता था, और लंबी अवधि के भंडारण में रेफरी के भंडारण की अनुमति देता था। लेकिन इसका मतलब यह है कि आप स्थानीय चर या पैरामीटर को रेफरी नहीं ले सकते हैं, जिन्हें आप अल्पकालिक भंडारण में रखना चाहते हैं क्योंकि उनके जीवन बहुत कम हैं।

सीएलआर टीम वास्तव में जिस तरह से चुना गया था, वह किसी भी रेफरी के दीर्घकालिक भंडारण को अस्वीकार करना था। किसी भी डिजाइन निर्णय की तरह, यह प्रतिस्पर्धी लक्ष्यों के खिलाफ कई ट्रेडऑफ का परिणाम था।

1

आपका टेस्ट कोड का आकलन नहीं होगा क्योंकि यह एक आदिम प्रकार है। लेकिन आपका दूसरा कोड काम करेगा क्योंकि यह एक संदर्भ प्रकार है। (यहां तक ​​कि 'रेफरी' की आवश्यकता नहीं है) उदाहरण को वापस असाइन करने की आवश्यकता नहीं है।

public class Second 
{ 
    public First f; 

    public Second(First f) 
    { 
     this.f= f; 
    } 

    public void change() 
    { 
     this.f.Name = "PUli"; 
    } 
} 
public class First 
{ 
    private string _name; 

    public First() 
    { 
     Name = "SUli"; 
    } 

    public string Name 
    { 
     get { return _name; } 
     set { _name = value; } 
    } 
} 
class Program 
{ 
    static void Main(String[] args) 
    { 
     First f = new First(); 
     Second sec = new Second(f); 
     Console.WriteLine(f.Name); 
     sec.change(); 
     Console.WriteLine(f.Name); 
    } 
} 

आउटपुट: -

Suli

पुली

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