यदि आप C प्रोग्रामर हैं, तो डेलीगेट्स को फ़ंक्शन के पॉइंटर्स के रूप में माना जा सकता है। हालांकि, C# में डेलीगेट्स एक साधारण फ़ंक्शन पॉइंटर से कहीं अधिक हैं। यह लेख डेलीगेट्स की अवधारणा और उनके दैनिक प्रोग्रामिंग में उपयोग की व्याख्या करता है।
अनिवार्य रूप से, डेलीगेट्स एक स्तर की अप्रत्यक्षता प्रदान करते हैं। वे कोड के एक टुकड़े को एनकैप्सुलेट करते हैं जिसे पास किया जा सकता है और टाइप-सेफ तरीके से निष्पादित किया जा सकता है। व्यवहार को तुरंत निष्पादित करने के बजाय, इसे एक ऑब्जेक्ट में समाहित किया जाता है। आप उस ऑब्जेक्ट पर कई क्रियाएं कर सकते हैं, और उनमें से एक है उस समाहित व्यवहार को निष्पादित करना।
डेलीगेट्स का उपयोग करके हम उच्च-क्रम फ़ंक्शन लिख सकते हैं, यानी फ़ंक्शन जो पैरामीटर के रूप में फ़ंक्शन प्राप्त कर सकते हैं या रिटर्न मान के रूप में फ़ंक्शन लौटा सकते हैं। एक डेलीगेट प्रकार उस मेथड सिग्नेचर को परिभाषित करता है जिसे डेलीगेट दर्शा सकता है, विशेष रूप से मेथड का रिटर्न प्रकार और उसके पैरामीटर प्रकार। निम्न उदाहरण में, Transformer एक डेलीगेट है जो किसी भी मेथड को दर्शा सकता है जो एक पूर्णांक स्वीकार करता है और एक पूर्णांक लौटाता है।
delegate int Transformer(int x);
हम किसी भी मेथड (लैम्ब्डा, इंस्टेंस, या स्टेटिक मेथड सहित) को Transformer के इंस्टेंस को असाइन कर सकते हैं जो सिग्नेचर को पूरा करता है। उदाहरण के लिए −
Transformer square = x => x * x; Transformer cube = x => x * x * x; Console.WriteLine(square(3)); // prints 9 Console.WriteLine(cube(5)); // prints 125
डेलीगेट्स का उपयोग कब करें?
डेलीगेट्स का उपयोग आमतौर पर तब किया जाता है जब कोड जो कुछ क्रियाओं को निष्पादित करना चाहता है, उन क्रियाओं के विवरण नहीं जानता लेकिन उन क्रियाओं का इंटरफ़ेस जानता है।
प्रोग्रामिंग में, हम अक्सर ऐसी स्थितियों का सामना करते हैं जहां हमें एक विशेष क्रिया निष्पादित करने की आवश्यकता होती है, लेकिन हम पहले से नहीं जानते कि उसे निष्पादित करने के लिए हम किस मेथड को कॉल करना चाहेंगे। डेलीगेट्स उस व्यवहार को डेलीगेट से प्रतिस्थापित करके और फिर उस डेलीगेट के एक ठोस इंस्टेंस को संदर्भ और स्थिति के अनुसार उपयुक्त व्यवहार के साथ पास करके इस समस्या को हल करने में हमारी मदद करते हैं।
एक डेलीगेट के कुछ भी करने के लिए, चार चीजें होने की आवश्यकता है −
1) डेलीगेट प्रकार घोषित किया जाना चाहिए।
एक डेलीगेट प्रकार अनिवार्य रूप से उस फ़ंक्शन की परिभाषा है जिसे वह दर्शा रहा है, यानी इसमें पैरामीटर प्रकार होते हैं जिन्हें फ़ंक्शन स्वीकार करेगा और एक रिटर्न प्रकार जो यह लौटाता है।
उदाहरण के लिए, एक डेलीगेट प्रकार जो एक मेथड को दर्शाता है जो दो संख्याओं को इनपुट के रूप में लेता है और एक संख्या लौटाता है, उसे इस प्रकार घोषित किया जा सकता है −
delegate int Processor(int numOne, int numTwo);
Processor एक प्रकार है, जो क्लास द्वारा बनाए गए प्रकार के समान है। इस प्रकार का इंस्टेंस बनाने के लिए, आपको एक मेथड की आवश्यकता होती है जो दो संख्याओं को इनपुट के रूप में लेता है और एक बूल लौटाता है।
2) निष्पादित किए जाने वाला कोड एक मेथड में समाहित होना चाहिए।
एक मेथड परिभाषित करें जिसमें उपरोक्त डेलीगेट प्रकार के समान सटीक सिग्नेचर हो और जो रनटाइम पर स्थिति के अनुसार आप जो चाहते हैं वह करता हो। उदाहरण के लिए, निम्न में से कोई भी मेथड Processor का इंस्टेंस बनाने के लिए उपयोग किया जा सकता है, क्योंकि वे सभी दो संख्याएं लेते हैं और एक संख्या लौटाते हैं।
static int Add(int numOne, int numTwo){ Return numOne + numTwo; } static int Subtract(int numOne, int numTwo){ Return numOne - numTwo; }3) एक डेलीगेट इंस्टेंस बनाया जाना चाहिए।
अब आपके पास एक डेलीगेट प्रकार और सही सिग्नेचर वाला एक मेथड है, आप उस डेलीगेट प्रकार का एक इंस्टेंस बना सकते हैं। ऐसा करने में, हम अनिवार्य रूप से C# कंपाइलर को बता रहे हैं कि जब डेलीगेट इंस्टेंस को इनवोक किया जाए तो इस मेथड को निष्पादित करें।
Processor processorOne = new Processor(Add); Processor processorTwo = new Processor(Subtract);
उपरोक्त उदाहरण मानता है कि Add और Subtract मेथड्स उसी क्लास में परिभाषित हैं जहां हम डेलीगेट का इंस्टेंस बना रहे हैं। यदि मेथड्स किसी अन्य क्लास में परिभाषित हैं, तो हमें उस क्लास का इंस्टेंस चाहिए होगा।
4) डेलीगेट इंस्टेंस को इनवोक किया जाना चाहिए।
यह केवल डेलीगेट इंस्टेंस पर एक मेथड कॉल करने की बात है, जिसका नाम, आश्चर्यजनक रूप से नहीं, Invoke है। डेलीगेट इंस्टेंस पर यह मेथड वही पैरामीटर सूची और रिटर्न प्रकार रखता है जो डेलीगेट प्रकार घोषणा निर्दिष्ट करती है। Invoke को कॉल करने से डेलीगेट इंस्टेंस की क्रिया निष्पादित होगी।
int sum = processorOne.Invoke(3, 5);
हालांकि, C# इसे और भी आसान बनाता है। आप सीधे डेलीगेट इंस्टेंस को इनवोक कर सकते हैं जैसे कि यह स्वयं एक मेथड हो। उदाहरण के लिए,
int difference = processorTwo(10, 6);
डेलीगेट्स को संयोजित करना और हटाना
यदि हम एक डेलीगेट इंस्टेंस के एकल इनवोकेशन के साथ विभिन्न क्रियाओं की सूची निष्पादित करना चाहते हैं, तो C# इसकी अनुमति देता है। System.Delegate प्रकार में दो स्टेटिक मेथड्स हैं, जिन्हें Combine और Remove कहा जाता है।
1. Combine
पैरामीटर के रूप में पास किए गए डेलीगेट्स के इनवोकेशन सूचियों को जोड़कर एक इनवोकेशन सूची के साथ एक नया डेलीगेट बनाता है। जब नया डेलीगेट इंस्टेंस इनवोक किया जाता है, तो इसकी सभी क्रियाएं क्रम में निष्पादित होती हैं।
public static Delegate Combine(params Delegate[] delegates); // OR public static Delegate Combine(Delegate a, Delegate b);
यदि इनवोकेशन सूची में कोई क्रिया अपवाद फेंकती है, तो वह बाद की किसी भी क्रिया को निष्पादित होने से रोकती है।
2. Remove
एक डेलीगेट की इनवोकेशन सूची के अंतिम घटना को दूसरी डेलीगेट की इनवोकेशन सूची से हटाता है। एक नया डेलीगेट लौटाता है जिसकी इनवोकेशन सूची स्रोत की इनवोकेशन सूची लेकर और मान की इनवोकेशन सूची के अंतिम घटना को हटाकर बनाई जाती है।
public static Delegate Remove(Delegate source, Delegate value);
सारांश
डेलीगेट्स एक विशेष प्रकार और पैरामीटर सेट के साथ व्यवहार को एनकैप्सुलेट करते हैं, जो एक सिंगल-मेथड इंटरफेस के समान है।
एक डेलीगेट प्रकार घोषणा द्वारा वर्णित प्रकार सिग्नेचर निर्धारित करता है कि किन मेथड्स का उपयोग डेलीगेट इंस्टेंस बनाने के लिए किया जा सकता है और इनवोकेशन के लिए सिग्नेचर।
एक डेलीगेट इंस्टेंस बनाने के लिए एक मेथड की आवश्यकता होती है जिसे हम डेलीगेट इनवोक होने पर निष्पादित करना चाहेंगे।
डेलीगेट इंस्टेंस अपरिवर्तनीय होते हैं, स्ट्रिंग्स के समान।
डेलीगेट इंस्टेंस प्रत्येक में एक इनवोकेशन सूची होती है - क्रियाओं की सूची।
डेलीगेट इंस्टेंस को एक दूसरे के साथ संयोजित और हटाया जा सकता है।
उदाहरण
using System; class Program{ delegate int Transformer(int x); delegate int Processor(int numOne, int numTwo); static void Main(){ Transformer square = x => x * x; Transformer cube = x => x * x * x; Console.WriteLine(square(3)); // prints 9 Console.WriteLine(cube(5)); // prints 125 Processor processorOne = new Processor(Add); Processor processorTwo = new Processor(Subtract); int sum = processorOne.Invoke(3, 5); Console.WriteLine(sum); // prints 8 int difference = processorTwo(10, 6); Console.WriteLine(difference); // prints 4 } static int Add(int numOne, int numTwo){ return numOne + numTwo; } static int Subtract(int numOne, int numTwo){ return numOne - numTwo; } }आउटपुट
9 125 8 4