C# में, अधिकांश मेथड्स में शून्य या अधिक पैरामीटर्स हो सकते हैं जो उस डेटा को परिभाषित करते हैं जो मेथड को प्रदान किया जाना चाहिए। मेथड को कॉल करने वाले किसी भी कोड को मेथड को डेटा (जिसे आर्गुमेंट्स कहा जाता है) पास करना होता है। एक मेथड अपने इनपुट को पैरामीटर्स के रूप में घोषित करता है, और उन्हें कॉलिंग कोड द्वारा आर्गुमेंट्स के रूप में प्रदान किया जाता है।
उदाहरण के लिए, निम्न मेथड और बाद के मेथड कॉल पर विचार करें।
static void Greet(string greeting){ Console.WriteLine(greeting); } ... Greet("Hello");उपरोक्त उदाहरण में, greeting Greet() मेथड का एक पैरामीटर है, और "Hello" मेथड को पास किया गया एक आर्गुमेंट है।
जब आप एक मेथड को कॉल करते हैं और आर्गुमेंट्स पास करते हैं, तो उन्हें मान द्वारा पास किया जाता है, जिसका अर्थ है कि मेथड को पास करते समय मान की एक कॉपी बनाई जाती है। मेथड के अंदर आर्गुमेंट में किए गए किसी भी परिवर्तन मूल वेरिएबल पर प्रतिबिंबित नहीं होते।
using System; int number = 8; Increase(number); Console.WriteLine(number); // prints 8 static void Increase(int num){ num = num + 1; Console.WriteLine(num); // prints 9 }जब आप एक संदर्भ प्रकार वेरिएबल पास करते हैं, जैसे एक ऑब्जेक्ट, C# अभी भी संदर्भ को मान द्वारा कॉपी करता है, क्योंकि वेरिएबल संदर्भ रखता है, वास्तविक ऑब्जेक्ट नहीं। इसलिए भले ही संदर्भ वेरिएबल की एक कॉपी पास की जाती है, दोनों मेमोरी में उसी ऑब्जेक्ट को संदर्भित करते हैं। इसलिए मेथड के अंदर वेरिएबल द्वारा ऑब्जेक्ट में किए गए किसी भी परिवर्तन मेथड के बाहर वेरिएबल को दिखाई देते हैं।
using System; var john = new User{ Name = "John", Salary = 50000 }; Promote(john); Console.WriteLine(john.Salary); // prints 60000 static void Promote(User u){ u.Salary += 10000; Console.WriteLine(u.Salary); // prints 60000 }हालांकि, यदि आप मेथड के अंदर वेरिएबल के मान को स्वयं बदलते हैं, तो वह परिवर्तन मेथड के बाहर प्रतिबिंबित नहीं होता, क्योंकि केवल कॉपी बदली गई थी, वास्तविक ऑब्जेक्ट नहीं। उदाहरण के लिए, हम मेथड के अंदर आर्गुमेंट को नल असाइन कर सकते हैं, और वास्तविक वेरिएबल अपरिवर्तित रहेगा।
using System; var john = new User{ Name = "John", Salary = 50000 }; Promote(john); Console.WriteLine(john.Salary); // prints 50000 static void Promote(User u){ u = null; }C# तीन अलग-अलग मॉडिफायर कीवर्ड्स की अनुमति देता है जिनका उपयोग करके आप मेथड्स के पैरामीटर्स को नियंत्रित कर सकते हैं।
ref मॉडिफायर
C# आपको ref मॉडिफायर का उपयोग करके पैरामीटर्स को संदर्भ द्वारा पास करने की अनुमति देता है। इससे कोई फर्क नहीं पड़ता कि पास किया जा रहा वेरिएबल संदर्भ प्रकार का है या मूल्य प्रकार का। पैरामीटर और आर्गुमेंट दोनों उसी मेमोरी लोकेशन को संदर्भित करेंगे।
निम्न उदाहरण में, आर्गुमेंट u को नल सेट करने से john वेरिएबल भी नल हो जाएगा, जिससे नल रेफरेंस एक्सेप्शन होगा।
उदाहरण
using System; var john = new User{ Name = "John", Salary = 50000 }; Promote(ref john); Console.WriteLine(john.Salary); // throws System.NullReferenceException static void Promote(ref User u){ u = null; }ref मॉडिफायर के साथ पास किया गया आर्गुमेंट पास करने से पहले आरंभ किया हुआ होना चाहिए।
out मॉडिफायर
यह ref मॉडिफायर के समान है, सिवाय इसके कि
आर्गुमेंट को फ़ंक्शन में जाने से पहले आरंभ करने की आवश्यकता नहीं है
फ़ंक्शन से बाहर आने से पहले आर्गुमेंट को आरंभ (असाइन) किया जाना चाहिए।
नीचे दिए गए उदाहरण में, Hire फ़ंक्शन out मॉडिफायर के माध्यम से पास किए गए एक नए यूज़र ऑब्जेक्ट को आरंभ करता है। ध्यान दें कि वेरिएबल john को Hire मेथड को कॉल करते समय ऑन-द-फ्लाई घोषित किया जाता है।
using System; Hire(out User john); Console.WriteLine(john.Salary); // prints 50000 static void Hire(out User u){ u = new User{ Name = "John", Salary = 50000 }; }ref मॉडिफायर की तरह, out मॉडिफायर द्वारा चिह्नित एक वेरिएबल संदर्भ द्वारा पास किया जाता है।
अक्सर एक out वेरिएबल का उपयोग किसी फ़ंक्शन से एकाधिक रिटर्न मान प्राप्त करने के लिए किया जाता है जैसे −
using System; var john = new User{ Name = "John", Salary = 50000 }; bool shouldPromote = Raise(john.Salary, out double hike); Console.WriteLine(shouldPromote); // True Console.WriteLine($"Hike Amount = {hike}"); // prints 5000 static bool Raise(int salary, out double hike){ hike = salary * 0.1; return hike < 7000; }in मॉडिफायर
यह ref और out पैरामीटर्स के समान है, सिवाय इसके कि in आर्गुमेंट स्वीकार करने वाले मेथड का मान आर्गुमेंट को संशोधित नहीं कर सकता। यदि यह प्रयास करता है, तो C# कंपाइलर कंपाइल-टाइम त्रुटि उत्पन्न करता है।
in पैरामीटर कंपाइलर को एक बड़े मूल्य प्रकार की मेमोरी को पैरामीटर वेरिएबल में कॉपी करने से बचाता है, साथ ही ऑब्जेक्ट को आकस्मिक संशोधन से रोकता है। यह उन्हें मेथड में बड़े मूल्य प्रकार को पास करते समय बहुत उपयोगी बनाता है।
var point = new Coord(); Verify(point); static void Verify(in Coord c){ // error: Cannot assign to variable 'in Coord' because it is a readonly variable c = new Coord(); } struct Coord{ public int X; public int Y; }उदाहरण
using System; class Program{ static void Main(){ int number = 8; Increase(number); Console.WriteLine(number); // prints 8 var john = new User { Name = "John", Salary = 50000 }; Promote(john); Console.WriteLine(john.Salary); // prints 60000 Leave(john); Console.WriteLine(john.Salary); // prints 60000 LeaveByRef(ref john); Console.WriteLine(john?.Salary); // prints nothing User dave; Hire(out dave); Console.WriteLine(dave.Salary); // prints 50000 } static void Increase(int num){ num = num + 1; Console.WriteLine(num); // prints 9 } static void Promote(User u){ u.Salary += 10000; Console.WriteLine(u.Salary); // prints 60000 } static void Leave(User u){ u = null; } static void LeaveByRef(ref User u){ u = null; } static void Hire(out User u){ u = new User{ Name = "John", Salary = 50000 }; } } class User{ public string Name { get; set; } public int Salary { get; set; } }आउटपुट
9 8 60000 60000 60000 50000