Delegates in C#

Delegates in C#: Delegate एक ऐसा Object होता है जो किसी Method को Refer कर सकता है। इसलिए जब हम कोई Delegate Create करते हैं, तो हम एक ऐसा Object Create कर रहे होते हैं, जो कि किसी दूसरे Method के Reference को Hold करता है। परिणामस्वरूप जिस Method को हम Delegate Object में Store करते हैं, उसे हम Delegate Object द्वारा Invoke भी कर सकते हैं।

सरल शब्दों में कहें तो Delegate एक प्रकार से C/C++ के Function Pointer की तरह होता है, जिसका प्रयोग करके हम किसी Function को उसके Pointer के माध्‍यम से Invoke कर सकते हैं। ठीक उसी तरह से C# का Delegate एक Object होता है, जो उस Method को Invoke कर सकता है, जिसे उसमें Store किया जाता है।

Delegate एक ऐसा Object होता है जो Data के रूप में एक या एक से अधिक Methods को Hold करता है। जैसाकि हम जानते हैं कि कोई Object कभी Execute नहीं होताए बल्कि Object हमेंशा Data व Operations का एक Encapsulated Unit होता है। लेकिन Delegate थोडा अलग तरह का Object होता है। क्योंकि हम Delegate Object को Method की तरह Execute कर सकते है और जब हम किसी Delegate को Execute करते हैं, तो उस Delegate में जिन Methods को Hold किया गया होता है, वे सभी Execute हो जाते हैं।

Delegate की एक मुख्‍य विशेषता ये है कि हम Delegate का प्रयोग करके Program के Runtime में Delegate द्वारा Referenced Methods के References को Change करके Dynamically अलग-अलग Methods को Invoke कर सकते हैं। परिणामस्वरूप हम Delegate का प्रयोग करके Polymorphism की सुविधा भी प्राप्त कर सकते हैं।

Declaration of Delegates in C#

Delegate किसी भी अन्‍य Class, Structure आदि की तरह एक User Defined Type होता है। लेकिन कोई Class या Structure वास्तव में Data Operations का Collection यानी Encapsulated Unit होता है, जबकि एक Delegate एक या एक से अधिक Methods यानी Predefined Operations का समूह होता है।

किसी भी अन्‍य User Defined Type को Create करने के लिए जिस तरह से हम किसी Keyword को Use करते हैं, ठीक उसी तरह से Delegate Type Create करने के लिए हमें delegate Keyword Use करना होता है।

Delegate Declaration, Method Declaration के समान ही दिखाई देता है। अन्तर केवल इतना है कि Method Declaration के साथ Method का Implementation भी होता है। जबकि Delegate Declaration में Method का Implementation Block नहीं होता। जैसे:

delegate string MyDelegate(string greeting);

जैसाकि हम इस Declaration द्वारा समझ सकते हैं कि यदि हम इस Statement से delegate Keyword को Remove कर दें] तो ये Statement एक Method Prototype या Method Signature की तरह ही दिखाई देता है।

यानी एक सामान्‍य Method और एक Delegate Type में केवल इतना ही अन्तर होता है कि Delegate Type की शु:आत delegate Keyword से होती है व Delegate Type के साथ Implementation Block Specified नहीं होता। जबकि Normal Method के साथ delegate Keyword का प्रयोग नहीं किया जाताए लेकिन Method Implementation Block जरूर होता है।

इस Declaration में Return Type (string) उस Method के Return Type को Specify कर रहा है, जिसे ये Delegate Invoke करेगा। जबकि इस Delegate का नाम MyDelegate है तथा MyDelegate में जिन Parameters को Specify किया गया है, जिस Method को ये Delegate Refer करेगा, उसमें भी यही Parameters Specify करने जरूरी हैं।

यानी जिन Methods को ये Delegate Refer करेगा, उन सभी का Return Type व Signature Exactly इसी Delegate Declaration में Specified Signature के समान ही होना चाहिए। परिणामस्वरूप जब हम एक बार Delegate Declare कर देते हैं, तो Declared Delegate से Matching Return TypeSignature वाले किसी भी Method को हम इस Delegate के माध्‍यम से Invoke कर सकते है। जबकि वह Matching Method कोई Static Method भी हो सकता है अथवा किसी Instance का Member Method भी हो सकता है।

Delegate Declare करने के बाद हमें उस Delegate Type का Reference Variable Create करना होता है और Delegate Type का एक नया Instance या Object Create करके उसका Reference इस Delegate Type के Reference Variable में Store करना होता है।

Newly Create होने वाले Delegate Object में किसी Method का Reference होता है, जिसका Signature व Return Type Exactly वैसा ही होता है, जैसा हमने Delegate Type Declare करते समय Specify किया होता है।

जब एक बार हम Delegate Type Define करके उसका नया Object Create कर लेते हैं, तो उस Object में हम समान Signature वाले Methods के नामों को Value के रूप में Store या Add कर सकते हैं।

परिणामस्वरूप Create होने वाले Delegate Object को हम अपने पूरे Program के दौरान हम Delegate को ठीक उसी तरह से Invoke कर सकते हैं, जिस तरह से किसी Method को Invoke करते हैं और जब हम Delegate को Invoke करते हैं, तो जो&जो Methods, Delegate में Stored होते हैं, वे सभी Execute हो जाते हैं।

DelegateClass दोनों को ही Create करने में एक समान Steps Included होते हैं, जिन्हें हम निम्न चित्र द्वारा आसानी से समझ सकते हैं:

Delegates in C# - Hindi - Delegates vs Class

Delegate को हम एक ऐसा Object मान सकते हैं, जिसमें Data के रूप में निम्न चित्रानुसार समान Return Type व Signatures के Methods के समूह की एक Ordered List होती है।

Delegates in C# - Hindi - Delegates Invocation List

Delegate में Contained Methods की इस List को Invocation List कहा जाता है।

जिन Methods को Delegate Hold करता है, उन्हें किसी Class या Structure में Define किया गया हो सकता है। लेकिन जिन Methods को Delegate में Contain करना होता है, उनका ref out Modifiers सहित SignatureReturn Type Delegate के Signature व Return Type के समान ही होना जरूरी होता है। साथ ही Invocation List के सभी Methods या तो किसी Instance यानी Object के Methods होते हैं अथवा Class के Static Methods होते हैं।

Delegate Object Creation

चूंकि Delegate Type भी एक Reference Type होता है, इसलिए Delegate Type, Reference भी होता है और Object भी। अत: Delegate Definition Create करने के बाद हमें new Operator को Use करते हुए Delegate Type का Delegate Create करना होता है और Newly Created Heap Memory Area के Object का Pointer Delegate Type के Reference Variable में Store करना होता है। जैसे:

MyDelegate reference;

Reference Create करने के बाद हमें Delegate Type का Object Create करना होता है। Delegate Object Create करने के लिए हम new Operator के साथ Delegate का नाम Specify करते हैं तथा Parenthesis के बीच हमें Invocation List के पहले Method को Specify करना होता है। जैसे:

reference = new MyDelegate(obj.Display);

जबकि यदि हम चाहें तो Delegate Object Creation के Shortcut Syntax को भी Specify कर सकते हैं, जिसमें हमें new Keyword के साथ Delegate का नाम Specify नहीं करना होताए बल्कि हम सी/ो ही Invocation List के First Method को Specify कर देते हैं। जैसे:

reference = obj.Display;

जबकि यदि हम चाहें तो Delegation Object Create करते ही उसे Invocation List के First Method से Initialize भी कर सकते हैं और ऐसा करने के लिए हम उपरोक्तानुसार दोनों तरीके Use कर सकते हैं। जैसे:

MyDelegate reference = new MyDelegate(obj.Display);
MyDelegate reference = obj.Display;

चूंकि Delegate, Reference Type होते हैं, इसलिए हम पूरे Program के दौरान कहीं पर भी Delegate के Reference को नया Reference Assign करके Change कर सकते हैं और हम Delegate Reference में जिस नए Method के Reference को Specify करते हैं, Delegate को Invoke करने पर वह Delegate Reference उसी Method को Invoke करता है।

Delegate Invocation

जब एक बार हम किसी Delegate को Declare करके उसे किसी नए Delegate Object का Reference Assign कर देते हैं, उसके बाद जिस Method को Newly Created Delegate Reference में Assign करते हैं, उस Method को Delegate Object के माध्‍यम से ठीक उसी तरह से Call किया जा सकता है, जिस तरह से C/C++ में किसी Normal Function को Call किया जाता है।

यानी हमें Delegate को किसी Object के नाम के साथ Dot Operator का प्रयोग करके अथवा Static Method की तरह किसी Class के नाम के साथ Dot Operator का प्रयोग करके Call करने की जरूरत नहीं होती। इस प्रक्रिया को समझने के लिए हम निम्नानुसार एक उदाहरण Program Create कर सकते हैं:

File Name: DelegateBasics.cs
using System;

namespace CSharpDelegate
{
    delegate void MyDelegate();	//Delegate Declaration

    class UsingDelegate
    {
        static void Main()
        {
            MyDelegate callMethod = new MyDelegate(Display);	//Delegate Object Creation
            callMethod();				//Call Display() via callMethod Delegate
        }

        public static void Display()
        {
            Console.WriteLine("This method executed from the UsingDelegate Class.");
        }
    }
}

Output:
	This method executed from the UsingDelegate Class.

ये Program काफी Simple लेकिन Delegate के Concept को आसानी से समझाने के लिए काफी है। इस Program में सबसे पहले हमने निम्नानुसार MyDelegate नाम का एक Delegate Type Declare किया है, ताकि C# Compiler समझ जाए कि हम इस Delegate द्वारा किस Signature व Return Type के Methods को Call कर सकेंगे%

    delegate void MyDelegate();      //Delegate Declaration

इस Declaration में हमने MyDelegate को No-Argument and No-Return Value Signature के साथ Declare किया है, जिसका मतलब ये है कि MyDelegate केवल उन्हीं Member Method व Static Methods को Invoke कर सकता है, जो No-Argument and No-Return Value Signature के साथ Define या Implement किए गए होंगे।

चूंकि किसी भी अन्‍य Type की तरह ही Delegate को केवल Declare कर देने मात्र से Delegate कोई काम नहीं कर सकता। बल्कि इसके Object को Data के रूप में उस Method का Reference Initialize या Assign करना होता है, जिसे Delegate के माध्‍यम से Invoke करना है।

इसलिए Main() Method में हमने निम्नानुसार Statement द्वारा callMethod नाम का एक MyDelegate Type का Reference Variable Create किया है और इस Reference Variable में new Operator का प्रयोग करके MyDelegate Type का Heap Memory Area Create किया है। साथ ही इस Newly Created Heap Area में MyDelegate Data के रूप में उस Method के नाम को Specify किया है, जिसे MyDelegate Type के callMethod Reference Variable द्वारा Invoke करना है:

MyDelegate callMethod = new MyDelegate(Display);            //Delegate Object Creation

चूंकि इस Program में हम callMethod, MyDelegate Reference Type द्वारा UsingDelegate नाम की Class में ही Defined Display() नाम के Static Method को Invoke करना चाहते है, जो कि MyDelegate के समान ही No-Argument and No-Return Value Signature के साथ Defined है। इसलिए Create होने वाले MyDelegate Type के Object में Parameter के रूप में हमने Display नाम को Specify किया है।

यहां ध्‍यान देने वाली बात ये है कि हालांकि Display() एक Method है, लेकिन Parameter में हमने केवल Display नाम Specify किया है, Parenthesis को नहीं। क्योंकि किसी भी Method के साथ Parenthesis को Specify करने पर Compiler को ये Instruction मिलता है कि हम उस Method को Invoke करना चाहते हैं।

जबकि उपरोक्त Statement में हम Display() Method को Invoke करना नहीं चाहते, बल्कि Display() Method का Reference, Data के रूप में MyDelegate Type के callMethod Reference Variable को Set करना चाहते हैं।

जब एक बार किसी Delegate Type के Reference Variable में Invoke किए जाने वाले Method का Reference, Delegate Data की तरह Set हो जाता है, उसके बाद हम पूरे Program में जहां चाहें वहां उस Referenced Method को Delegate के माध्‍यम से Invoke कर सकते है। इसीलिए उपरोक्त Program में जब निम्न Statement Execute होता है:

callMethod();               //Call Display() via callMethod Delegate

तो UsingDelegate Class में ही Defined Display() नाम का Static Method Invoke हो जाता है, क्योंकि callMethod() नाम के MyDelegate Type Reference Variable में इसी Display() Method का Reference Data के रूप में Stored है।

ध्‍यान दें कि हालांकि callMethod() वास्तव में MyDelegate Type का एक Object है, लेकिन फिर भी हम इसे C/C++ के Normal Function की तरह Invoke कर रहे हैं। हम ऐसा इसलिए कर सकते हैं, क्योंकि जैसाकि हमने पहले भी कहा कि Compiler को जब भी कोई Parenthesis Pair मिलता है, Compiler उस Parenthesis से Just पहले Specified Identifier को एक Executable Method की तरह Treat करने लगता है।

इसलिए जब हम MyDelegate Type के callMethod Reference Variable के साथ Parenthesis को Specify करते हैं, तो C# Compiler इसे एक Executable Method की तरह Treat करने लगता है।

चूंकि इस callMethod Reference Variable में हमने Data के रूप में UsingDelegate Class में Defined Display() नाम के Static Method का Reference Store किया है। इसलिए C# Compiler जब इस Object को Method की तरह Invoke करता है, तो वास्तव में वह इस Object के अन्दर Data के रूप में Stored Display() Method के Reference को ही Invoke करता है। परिणामस्वरूप callMethod को Method की तरह Call करने पर Display() नाम का Static Method Execute हो जाता है।

C# Interface Example
C# Delegate Example

C# in Hindiये Article इस वेबसाईट पर Selling हेतु उपलब्‍ध EBook C#.NET in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी। 

C#.NET in Hindi | Page:908 | Format: PDF

BUY NOW GET DEMO REVIEWS