दिलचस्प पोस्ट
ग्रहण सफलतापूर्वक संकलित करता है लेकिन अभी भी अर्थ त्रुटियाँ देता है क्या ड्राइव का एसएसडी है, इसका पता लगाने का कोई तरीका क्या है? एक निर्बाध प्रक्रिया क्या है? Android पर `startActivityForResult` का प्रबंधन कैसे करें? उपप्रोसेस पॉपने पायथन का उपयोग कैसे करें NullPointerException onCreate में दृश्यों को एक्सेस करना () कैसे सी # में एक एक्सेल फ़ाइल खोलने के लिए? क्यों नहीं चार डेटा का पता प्रदर्शित है? अंतिम आइटम को पायथन इटरेटर से प्राप्त करने का सबसे सुरक्षित तरीका जॉप्शनपैन.शोइनपुटडियलोग में एकाधिक इनपुट वसंत के बीच अंतर @ नियंत्रक और @ आरक्षित नियंत्रक एनोटेशन YAML और JSON के बीच अंतर क्या है? जब एक दूसरे से अधिक पसंद करते हैं प्रतिस्थापन के रूप में डॉलर चिह्न ($) का उपयोग करते समय `string.replace` अजीब व्यवहार अपलोड करने से पहले एक छवि पूर्वावलोकन दिखाएं एक गतिविधि संदर्भ के बाहर से शुरू कर रहा है

'रेफरी' और 'आउट' कीवर्ड के बीच अंतर क्या है?

मैं उस फ़ंक्शन का निर्माण कर रहा हूं जहां मुझे ऑब्जेक्ट पास करने की आवश्यकता है ताकि फ़ंक्शन द्वारा इसे संशोधित किया जा सके। के बीच क्या अंतर है:

public void myFunction(ref MyClass someClass) 

तथा

 public void myFunction(out MyClass someClass) 

मुझे किस का उपयोग करना चाहिए और क्यों?

वेब के समाधान से एकत्रित समाधान "'रेफरी' और 'आउट' कीवर्ड के बीच अंतर क्या है?"

ref कंपाइलर को बताता है कि ऑब्जेक्ट फ़ंक्शन में प्रवेश करने से पहले आरंभ किया जाता है, जबकि out संकलक को बताता है कि ऑब्जेक्ट फ़ंक्शन के अंदर आरंभीकरण किया जाएगा।

इसलिए जब ref दो-तरीकों से होती है, आउट-आउट केवल

ref मॉडरेटर का मतलब है कि:

  1. मूल्य पहले से सेट है और
  2. विधि इसे पढ़ और संशोधित कर सकती है।

out संशोधक का मतलब है कि:

  1. वैल्यू निर्धारित नहीं है और विधि द्वारा तब तक पढ़ा नहीं जा सकता जब तक कि इसे सेट न किया जाए।
  2. विधि को लौटने से पहले इसे सेट करना होगा

मान लें कि डोम पीपीएस के कक्ष में टीपीएस रिपोर्ट के बारे में मेमो के बारे में दिखाता है।

यदि डोम एक रेफरी तर्क था, तो उनके पास ज्ञापन की एक मुद्रित कॉपी होगी।

अगर डोम बाहर तर्क थे, तो वह उसे अपने साथ लेने के लिए पीटर को एक ज्ञापन की एक नई प्रति प्रिंट करवाएगा।

मैं एक स्पष्टीकरण में अपने हाथ की कोशिश करने जा रहा हूँ:

मुझे लगता है कि हम समझते हैं कि मूल्य प्रकार कैसे सही काम करते हैं? मान प्रकार (इंट, लम्बे, स्ट्रक्चर आदि) हैं जब आप उन्हें एक रिफ आदेश के बिना फ़ंक्शन में भेजते हैं, तो डेटा को कॉपी करता है । जो कुछ भी आप फ़ंक्शन में उस डेटा पर करते हैं वह केवल प्रतिलिपि को प्रभावित करता है, मूल नहीं। रिफ आदेश वास्तविक डेटा भेजता है और किसी भी परिवर्तन समारोह के बाहर डेटा को प्रभावित करेगा।

भ्रामक भाग पर ठीक है, संदर्भ प्रकार:

एक संदर्भ प्रकार बनाने देता है:

 List<string> someobject = new List<string>() 

जब आप नया ऑबजेक्ट करते हैं , तो दो भागों बनते हैं:

  1. स्मृति के ब्लॉक जो किसी ऑब्जेक्ट के लिए डेटा रखता है।
  2. डेटा के उस ब्लॉक में एक संदर्भ (सूचक)

अब जब आप रीफ के बिना किसी विधि में कोई ऑब्जेक्ट भेजते हैं तो यह संदर्भ सूचक, नहीं डेटा नहीं है। तो अब आपके पास यह है:

 (outside method) reference1 => someobject (inside method) reference2 => someobject 

एक ही ऑब्जेक्ट की ओर इशारा करते दो संदर्भ यदि आप संदर्भ 2 का उपयोग करते हुए एओबीजेड पर कोई संपत्ति संशोधित करते हैं तो यह संदर्भ 1 द्वारा इंगित किए गए समान डेटा को प्रभावित करेगा।

  (inside method) reference2.Add("SomeString"); (outside method) reference1[0] == "SomeString" //this is true 

यदि आप संदर्भ 2 को हटा दें या इसे नए डेटा पर इंगित करें, तो यह संदर्भ 1 को प्रभावित नहीं करेगा और न ही डेटा संदर्भ 1 को इंगित करेगा।

 (inside method) reference2 = new List<string>(); (outside method) reference1 != null; reference1[0] == "SomeString" //this is true The references are now pointing like this: reference2 => new List<string>() reference1 => someobject 

अब क्या होता है जब आप किसी विधि के संदर्भ में एओबीजेस भेजते हैं? किसी वस्तु को वास्तविक संदर्भ भेज दिया जाता है। तो अब आपके पास डेटा का एक ही संदर्भ है:

 (outside method) reference1 => someobject; (inside method) reference1 => someobject; 

लेकिन इसका क्या मतलब है? यह दो मुख्य बातों को छोड़कर रेब के द्वारा कोई ऑब्जेक्ट भेजने के बिल्कुल वैसा ही काम करता है:

1) जब आप विधि के अंदर संदर्भ बाहर निकलते हैं, तो यह विधि के बाहर एक को समाप्त कर देगा।

  (inside method) reference1 = null; (outside method) reference1 == null; //true 

2) अब आप पूरी तरह से अलग डेटा स्थान के संदर्भ को इंगित कर सकते हैं और फ़ंक्शन के बाहर का संदर्भ अब नए डेटा स्थान पर इंगित करेगा।

  (inside method) reference1 = new List<string>(); (outside method) reference1.Count == 0; //this is true 

रेफरी में और बाहर है

आपकी आवश्यकताओं के लिए जहां भी यह पर्याप्त होता है आपको वरीयता में उपयोग करना चाहिए।

कुत्ते का विस्तार, बिल्ली का उदाहरण। रेफरी के साथ दूसरी विधि कॉलर द्वारा संदर्भित ऑब्जेक्ट को बदल देती है। इसलिए "बिल्ली" !!!

  public static void Foo() { MyClass myObject = new MyClass(); myObject.Name = "Dog"; Bar(myObject); Console.WriteLine(myObject.Name); // Writes "Dog". Bar(ref myObject); Console.WriteLine(myObject.Name); // Writes "Cat". } public static void Bar(MyClass someObject) { MyClass myTempObject = new MyClass(); myTempObject.Name = "Cat"; someObject = myTempObject; } public static void Bar(ref MyClass someObject) { MyClass myTempObject = new MyClass(); myTempObject.Name = "Cat"; someObject = myTempObject; } 

बाहर:

सी # में, एक विधि केवल एक मान वापस कर सकती है। यदि आप एक से अधिक मान वापस करना चाहते हैं, तो आप बाहर के कीवर्ड का उपयोग कर सकते हैं। रिटर्न-बाय-रेफरेंस के रूप में बाहर संशोधक रिटर्न सरलतम उत्तर यह है कि विधि "से बाहर" का प्रयोग विधि से मूल्य प्राप्त करने के लिए किया जाता है।

  1. आपको कॉलिंग फ़ंक्शन में मान को प्रारंभ करने की आवश्यकता नहीं है।
  2. आपको फ़ंक्शन को मान निर्दिष्ट करना होगा, अन्यथा कंपाइलर एक त्रुटि की रिपोर्ट करेगा

रेफरी:

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

  1. फ़ंक्शन को कॉल करने से पहले आपको वैरिएबल को इनिशियलाइज़ करना होगा।
  2. विधि में रेफ़ पैरामीटर को किसी भी मूल्य को असाइन करना अनिवार्य नहीं है। यदि आप मूल्य नहीं बदलते हैं, तो इसे "रेफरी" के रूप में चिह्नित करने की क्या आवश्यकता है?

चूंकि आप किसी संदर्भ प्रकार (एक कक्षा) में गुजर रहे हैं, इसलिए कोई ज़रूरत नहीं है क्योंकि प्रति डिफ़ॉल्ट केवल वास्तविक ऑब्जेक्ट का संदर्भ पारित किया जाता है और इसलिए आप संदर्भ के पीछे हमेशा वस्तु बदलते हैं।

उदाहरण:

 public void Foo() { MyClass myObject = new MyClass(); myObject.Name = "Dog"; Bar(myObject); Console.WriteLine(myObject.Name); // Writes "Cat". } public void Bar(MyClass someObject) { someObject.Name = "Cat"; } 

जब तक आप किसी कक्षा में गुजारें तो आप ref का इस्तेमाल नहीं करते हैं यदि आप ऑब्जेक्ट को अपनी विधि में बदलना चाहते हैं।

ref out और इसी प्रकार के अंतर को छोड़कर समान व्यवहार करना

  • ref वेरिएबल का उपयोग करने से पहले आरंभ किया जाना चाहिए। बिना आउटएबल के उपयोग किए जा सकते हैं
  • out पैरामीटर का उपयोग करने वाले फ़ंक्शन द्वारा असाइन किए गए मान के रूप में होना चाहिए। इसलिए, हम कॉलिंग कोड में प्रारंभिक पैरामीटर का उपयोग कर सकते हैं, लेकिन फ़ंक्शन निष्पादित होने पर मूल्य खो जाएगा।

"बेकर, नानबाई"

ऐसा इसलिए है क्योंकि पहले एक "स्ट्रैच-रेफरेंस" को "बेकर" को इंगित करता है। संदर्भ बदलना संभव है क्योंकि आप इसे रेफ़िकोड किए गए कीवर्ड (=> एक स्ट्रिंग के संदर्भ के संदर्भ) के माध्यम से पास कर चुके हैं। दूसरी कॉल को स्ट्रिंग के संदर्भ की एक कॉपी मिलती है।

स्ट्रिंग पहले किसी विशेष प्रकार का दिखता है लेकिन स्ट्रिंग सिर्फ एक संदर्भ वर्ग है और यदि आप परिभाषित करते हैं

 string s = "Able"; 

फिर एस एक स्ट्रिंग क्लास के लिए एक संदर्भ है जिसमें "Able" टेक्स्ट है! एक ही चर के माध्यम से एक अन्य असाइनमेंट

 s = "Baker"; 

मूल स्ट्रिंग नहीं बदलता है, लेकिन सिर्फ एक नया उदाहरण बनाता है और उस उदाहरण को इंगित करता है!

आप निम्न छोटे कोड उदाहरण के साथ कोशिश कर सकते हैं:

 string s = "Able"; string s2 = s; s = "Baker"; Console.WriteLine(s2); 

आप क्या उम्मीद करते हैं? आपको क्या मिलेगा अभी भी "ऐबल" है क्योंकि आप सिर्फ एक दूसरे उदाहरण में संदर्भ सेट करते हैं जबकि एस 2 मूल आवृत्ति को इंगित करता है।

संपादित करें: स्ट्रिंग भी अपरिवर्तनीय है जिसका मतलब है कि कोई विधि या संपत्ति नहीं है जो एक मौजूदा स्ट्रिंग इन्सेंटेशन को संशोधित करती है (आप डॉक्स में एक को ढूंढने का प्रयास कर सकते हैं, लेकिन आप कोई भी पंख नहीं करेंगे :-))। सभी स्ट्रिंग हेरफेर पद्धतियां एक नई स्ट्रिंग आवृत्ति वापस आती हैं! (यही कारण है कि आप अक्सर स्ट्रिंगबइल्डर वर्ग का उपयोग करते समय बेहतर प्रदर्शन प्राप्त करते हैं)

आउट: फ़ंक्शन से केवल एक मान लौटने के लिए एक रिटर्न स्टेटमेंट का उपयोग किया जा सकता है। हालांकि, आउटपुट पैरामीटर का उपयोग करके, आप फ़ंक्शन से दो मान वापस कर सकते हैं। आउटपुट पैरामीटर संदर्भ पैरामीटर की तरह होते हैं, सिवाय इसके कि वे डेटा को इसके बजाय विधि के बाहर स्थानांतरित करते हैं।

निम्नलिखित उदाहरण यह दर्शाता है:

 using System; namespace CalculatorApplication { class NumberManipulator { public void getValue(out int x ) { int temp = 5; x = temp; } static void Main(string[] args) { NumberManipulator n = new NumberManipulator(); /* local variable definition */ int a = 100; Console.WriteLine("Before method call, value of a : {0}", a); /* calling a function to get the value */ n.getValue(out a); Console.WriteLine("After method call, value of a : {0}", a); Console.ReadLine(); } } } 

रेफरी: एक संदर्भ पैरामीटर एक चर के स्मृति स्थान का एक संदर्भ है। जब आप संदर्भ के आधार पर पैरामीटर पास करते हैं, मान पैरामीटर के विपरीत, इन पैरामीटर के लिए एक नया स्टोरेज स्थान नहीं बनाया गया है। संदर्भ पैरामीटर उसी स्मृति स्थान को वास्तविक पैरामीटर के रूप में दर्शाता है जो कि विधि के लिए आपूर्ति की जाती हैं।

सी # में, आप रेफ़ कीवर्ड के संदर्भ संदर्भ पैरामीटर घोषित करते हैं। निम्नलिखित उदाहरण यह दर्शाता है:

 using System; namespace CalculatorApplication { class NumberManipulator { public void swap(ref int x, ref int y) { int temp; temp = x; /* save the value of x */ x = y; /* put y into x */ y = temp; /* put temp into y */ } static void Main(string[] args) { NumberManipulator n = new NumberManipulator(); /* local variable definition */ int a = 100; int b = 200; Console.WriteLine("Before swap, value of a : {0}", a); Console.WriteLine("Before swap, value of b : {0}", b); /* calling a function to swap the values */ n.swap(ref a, ref b); Console.WriteLine("After swap, value of a : {0}", a); Console.WriteLine("After swap, value of b : {0}", b); Console.ReadLine(); } } } 

रेफरी का मतलब है कि रेफ़ पैरामीटर में मान पहले ही सेट है, विधि इसे पढ़ और संशोधित कर सकती है। रेफ़िकोड कीवर्ड का उपयोग करना यह कहने के समान है कि कॉलर पैरामीटर के मूल्य को आरंभ करने के लिए उत्तरदायी है।


बाहर संकलक बताता है कि ऑब्जेक्ट का आरंभीकरण फ़ंक्शन की जिम्मेदारी है, फ़ंक्शन को आउट पैरामीटर को असाइन करना होगा। उसे अनअसाइनमेंट छोड़ने की अनुमति नहीं है।

यहां पढ़ें

रेफरी और आउट का काम सिर्फ संदर्भों से गुजरने और सी ++ के रूप में पॉइंटर्स से गुजरने की तरह

रेफरी के लिए, तर्क को घोषित और आरम्भ किया जाना चाहिए।

बाहर के लिए, तर्क को घोषित करना चाहिए, लेकिन आरंभिक रूप से शुरू नहीं किया जा सकता है या नहीं

  double nbr = 6; // if not initialized we get error double dd = doit.square(ref nbr); double Half_nbr ; // fine as passed by out, but inside the calling method you initialize it doit.math_routines(nbr, out Half_nbr); 

उन लोगों के लिए जो उदाहरण से सीखते हैं (जैसे मेरी) यहां एंथोनी कोल्सोव कह रहा है ।

मैंने रेफरी, आउट, और अन्य के कुछ न्यूनतम उदाहरणों को बिन्दु बनाने के लिए बनाया है। मैं सर्वोत्तम प्रथाओं को कवर नहीं कर रहा हूं, मतभेदों को समझने के लिए बस उदाहरण

https://gist.github.com/2upmedia/6d98a57b68d849ee7091

वे बहुत ज्यादा समान हैं- केवल इतना अंतर यह है कि एक चर जो आप एक बाहर के पैरामीटर के रूप में पास करते हैं, उसे आरंभ करने की आवश्यकता नहीं होती है, और रिफ पैरामीटर का उपयोग करने वाला तरीका उसे कुछ सेट करना है

 int x; Foo(out x); // OK int y; Foo(ref y); // Error 

रेफरी पैरामीटर डेटा के लिए है जिसे संशोधित किया जा सकता है, पैरामीटर पैरामीटर डेटा के लिए हैं जो फंक्शन के लिए एक अतिरिक्त आउटपुट (उदाहरण के लिए int.TryParse) है जो पहले से कुछ के लिए रिटर्न वैल्यू का उपयोग कर रहे हैं

  public static void Main(string[] args) { //int a=10; //change(ref a); //Console.WriteLine(a); // Console.Read(); int b; change2(out b); Console.WriteLine(b); Console.Read(); } // static void change(ref int a) //{ // a = 20; //} static void change2(out int b) { b = 20; } 

आप इस कोड की जांच कर सकते हैं, जब आप "रेफरी" का उपयोग करते हैं, तो इसका अर्थ आप पूरी तरह से भिन्नता का वर्णन करेंगे, इसका मतलब यह है कि आप पहले से ही int / string को इनिशियलाइज़ करते हैं

लेकिन जब आप "बाहर" का उपयोग करते हैं तो यह दोनों स्थितियों में काम करता है wheather u उस int / string को प्रारंभ करता है, लेकिन उस फ़ंक्शन को उस int / string को प्रारंभ करना चाहिए

नीचे मैंने रेफरी और आउट दोनों का उपयोग करते हुए एक उदाहरण दिखाया है । अब, आप सभी को रेफरी और आउट के बारे में साफ कर दिया जाएगा।

नीचे दिए गए उदाहरण में, जब मैं टिप्पणी करता / / myRefObj = नया myClass {नाम = "रेफरी बाहर बुलाया !!"}; लाइन, "अनअसाइन स्थानीय वैरिएबल 'myRefObj' का प्रयोग" कहकर एक त्रुटि मिल जाएगी, लेकिन इसमें कोई त्रुटि नहीं है

रेफरी का उपयोग करने के लिए कहां : जब हम एक पैरामीटर में किसी प्रक्रिया को बुला रहे हैं और उसी पैरामीटर का उपयोग उस proc के आउटपुट को संग्रहीत करने के लिए किया जाएगा।

आउट का उपयोग करने के लिए: जब हम कोई पैरामीटर में कोई प्रक्रिया नहीं बुला रहे हैं और उसी परम का उपयोग उस proc से मान वापस करने के लिए किया जाएगा आउटपुट को भी ध्यान दें

 public partial class refAndOutUse : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { myClass myRefObj; myRefObj = new myClass { Name = "ref outside called!! <br/>" }; myRefFunction(ref myRefObj); Response.Write(myRefObj.Name); //ref inside function myClass myOutObj; myOutFunction(out myOutObj); Response.Write(myOutObj.Name); //out inside function } void myRefFunction(ref myClass refObj) { refObj.Name = "ref inside function <br/>"; Response.Write(refObj.Name); //ref inside function } void myOutFunction(out myClass outObj) { outObj = new myClass { Name = "out inside function <br/>" }; Response.Write(outObj.Name); //out inside function } } public class myClass { public string Name { get; set; } } 

एक विधि के दृष्टिकोण से जो एक पैरामीटर प्राप्त करता है, ref और out बीच का अंतर यह है कि सी # को यह आवश्यक है कि लौटने से पहले सभी तरीकों से तरीकों को लिखना चाहिए, और ऐसा कोई पैरामीटर के साथ कुछ भी नहीं करना चाहिए, अन्य पैरामीटर या इसे लिखना, जब तक कि इसे किसी अन्य पद्धति के रूप में पारित नहीं किया जाता out या सीधे लिखित रूप में लिखा जाता है। ध्यान दें कि कुछ अन्य भाषा ऐसी आवश्यकताओं को लागू नहीं करती हैं; एक वर्चुअल या इंटरफ़ेस पद्धति जिसे सी # में एक पैरामीटर के साथ घोषित किया गया है, उस पर दूसरी भाषा में ओवरराइड किया जा सकता है जो ऐसे पैरामीटरों पर किसी विशेष प्रतिबंध को लागू नहीं करता है।

कॉलर के दृष्टिकोण से, सी # कई परिस्थितियों में मान लेंगे कि किसी बाह्य पैरामीटर के साथ एक विधि को बुलाते समय पहले पढ़े बिना लिखने वाले पारित वैरिएबल का कारण होगा। यह धारणा सही नहीं हो सकता जब अन्य भाषाओं में लिखी गई विधियों को बुलाया जा सके। उदाहरण के लिए:

 struct MyStruct { ... myStruct(IDictionary<int, MyStruct> d) { d.TryGetValue(23, out this); } } 

यदि myDictionary IDictionary<TKey,TValue> myDictionary IDictionary<TKey,TValue> कार्यान्वयन को सी # के अलावा किसी अन्य भाषा में लिखा गया है, भले ही MyStruct s = new MyStruct(myDictionary); एक असाइनमेंट की तरह दिखता है, यह संभावित रूप से अनधिकृत रूप से छोड़ सकता है

ध्यान दें कि वीबी.नेट में लिखा गया कंसल्टर्स, सी # के विपरीत, कोई धारणा नहीं करते हैं कि क्या विधियां किसी भी out पैरामीटर को संशोधित करती हैं, और सभी क्षेत्रों को बिना शर्त तरीके से साफ़ कर देती हैं। ऊपर वर्णित अजीब व्यवहार VB में पूरी तरह से लिखा हुआ कोड या C # में नहीं होगा, लेकिन जब सी # में लिखे गए कोड VB.NET में लिखी गई विधि को कहते हैं तो हो सकता है।

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

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

 public class Example { public static void Main() { int val1 = 0; //must be initialized int val2; //optional Example1(ref val1); Console.WriteLine(val1); Example2(out val2); Console.WriteLine(val2); } static void Example1(ref int value) { value = 1; } static void Example2(out int value) { value = 2; } } /* Output 1 2 

विधि ओवरलोडिंग में रेफरी और आउट

रेफरी और आउट दोनों तरीकों से ओवरलोडिंग में एक साथ इस्तेमाल नहीं किया जा सकता। हालांकि, रेफरी और आउट को समय-समय पर अलग तरह से व्यवहार किया जाता है, लेकिन उन्हें संकलन समय पर ही व्यवहार किया जाता है (सीएलआर दोनों के बीच अंतर नहीं करता है जबकि यह रेफरी और आउट के लिए आईएल बनाता था)।

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

ref में अच्छी तरह से समझाया गया है, लेकिन ध्यान रखें कि ref को अपरिष्कृत ऑब्जेक्ट के साथ बुलाया जा सकता है

इस उदाहरण को देखें – एस 1 के दायरे को ध्यान में रखें

 public class Class1 { // uninitialized private string s1; public Class1() { // no issue here.. RefEater(ref s1); // Error CS0165 Use of unassigned local variable 's2' //string s2; //RefEater(ref s2); } private void RefEater(ref string s) { } } 

संलेखन समय:

(1) हम कॉलिंग विधि को Main() बनाते हैं Main()

(2) यह एक सूची वस्तु (जो एक संदर्भ प्रकार ऑब्जेक्ट है) बनाता है और उसे चर myList में संग्रहीत करता है

 public sealed class Program { public static Main() { List<int> myList = new List<int>(); 

रनटाइम के दौरान:

(3) रनटाइम # 00 पर स्टैक पर मेमोरी को आवंटित करता है, एक पता स्टोर करने के लिए पर्याप्त (# 00 = myList , चूंकि वेरिएबल नाम वास्तव में मेमोरी स्थान के लिए उपनाम हैं)

(4) रनटाइम मेमोरी स्थान # एफएफ पर हीप पर सूची ऑब्जेक्ट बनाता है (ये सभी पते उदाहरण के लिए हैं)

(5) रनटाइम तब # 00 पर ऑब्जेक्ट के प्रारंभिक पते # myList स्टोर करेगा (या शब्दों में, सूचक myList में सूची ऑब्जेक्ट का संदर्भ संग्रहीत करता है)

ऑथरिंग टाइम पर वापस जाएं:

(6) हम तब सूची ऑब्जेक्ट को myParamList रूप में बुलाया विधि को myParamList करने के लिए modifyMyList और इसे एक नई सूची ऑब्जेक्ट असाइन करें

 List<int> myList = new List<int>(); List<int> newList = ModifyMyList(myList) public List<int> ModifyMyList(List<int> myParamList){ myParamList = new List<int>(); return myParamList; } 

रनटाइम के दौरान:

(7) रनटाइम कॉल की गई विधि के लिए कॉल रूटीन शुरू करता है और इसके भाग के रूप में, मापदंडों के प्रकार की जांच करता है।

(8) संदर्भ प्रकार को खोजने के बाद, यह पैरामीटर चर myParamList अलियासिंग के लिए # 04 पर स्टैक पर स्मृति को आवंटित करता है।

(9) यह तब उसमें मूल्य # एफएफ भी स्टोर करता है

(10) रनटाइम स्मृति स्थान # 004 पर ढेर पर एक सूची ऑब्जेक्ट बनाता है और # 4 में इस वैल्यू के साथ # एफएफ की जगह लेता है (या मूल सूची ऑब्जेक्ट की व्याख्या और इस विधि में नई सूची ऑब्जेक्ट की ओर इशारा किया गया है)

# 00 में पता नहीं बदला है और # myList (या मूल myList सूचक को परेशान नहीं है) के संदर्भ को बरकरार रखता है।


रेफरेड कीवर्ड एक (8) और (9) के लिए रनटाइम कोड को छोड़ने के लिए एक कंपाइलर निर्देश है, जिसका अर्थ है कि विधि मापदंडों के लिए कोई ढेर आवंटन नहीं होगा। #FF पर ऑब्जेक्ट पर काम करने के लिए यह मूल # 00 पॉइंटर का उपयोग करेगा यदि मूल सूचक आरंभीकृत नहीं हुआ है, तो रनटाइम शिकायतें बंद कर देगी, क्योंकि इसे चालू नहीं किया जा सकता है क्योंकि चर को प्रारंभ नहीं किया गया है

बाहर की कीवर्ड एक कंपाइलर निर्देश है जो (9) और (10) पर मामूली संशोधन के साथ रेफरी के बराबर है। कंपाइलर को उम्मीद है कि तर्क अपरिहार्य हो जाएगा और (8), (4) और (5) के साथ हीप पर ऑब्जेक्ट बनाने और तर्क चर में अपना आरंभिक पता संग्रहीत करने के लिए जारी रहेगा। कोई अपरिभाषित त्रुटि नहीं डाली जाएगी और संग्रहीत कोई भी पिछला संदर्भ खो जाएगा।

अच्छी तरह से ध्यान दें कि फ़ंक्शन के अंदर पारित किया गया संदर्भ पैरामीटर सीधे काम करता है।

उदाहरण के लिए,

  public class MyClass { public string Name { get; set; } } public void Foo() { MyClass myObject = new MyClass(); myObject.Name = "Dog"; Bar(myObject); Console.WriteLine(myObject.Name); // Writes "Dog". } public void Bar(MyClass someObject) { MyClass myTempObject = new MyClass(); myTempObject.Name = "Cat"; someObject = myTempObject; } 

यह कुत्ता, बिल्ली नहीं लिखेंगे इसलिए आपको सीधे कुछ ऑब्जेक्ट पर काम करना चाहिए।

मैं इस पर इतना अच्छा नहीं हो सकता, लेकिन निश्चित रूप से तार (भले ही वे तकनीकी रूप से संदर्भ प्रकार हैं और ढेर पर रहते हैं) मूल्य से पारित नहीं हैं, संदर्भ नहीं है?

  string a = "Hello"; string b = "goodbye"; b = a; //attempt to make b point to a, won't work. a = "testing"; Console.WriteLine(b); //this will produce "hello", NOT "testing"!!!! 

यह आपको रेफरी की आवश्यकता क्यों है यदि आप चाहते हैं कि उन्हें फ़ंक्शन बनाने के दायरे के बाहर मौजूद परिवर्तन हो, तो आप कोई अन्य संदर्भ नहीं दे रहे हैं।

जहाँ तक मुझे पता है कि आपको केवल structs / value types के लिए रेफरी की आवश्यकता होती है और स्ट्रिंग ही होती है, क्योंकि स्ट्रिंग एक संदर्भ प्रकार है जो दिखावा करता है लेकिन मूल्य प्रकार नहीं है।

मैं यहाँ पूरी तरह से गलत हो सकता है, हालांकि, मैं नया हूँ