डेलिगेट क्या है? [बन्द है]


152

मुझे भ्रम है कि एक प्रतिनिधि की वास्तविक भूमिका क्या है?

मुझे अपने साक्षात्कारों में कई बार यह सवाल पूछा गया है, लेकिन मुझे नहीं लगता कि साक्षात्कारकर्ता मेरे उत्तर से संतुष्ट थे।

क्या कोई मुझे एक उदाहरण में, एक व्यावहारिक उदाहरण के साथ, सबसे अच्छी परिभाषा बता सकता है?


21
जिज्ञासा से बाहर, आपने क्या जवाब दिया ताकि हम आपको बता सकें कि आप इसे कैसे सही कर सकते हैं?
एंथनी फोर्लोनी

6
मुझे यह दिलचस्प लगता है कि यह सवाल बंद कर दिया गया था, लेकिन 126 अपवोट्स हैं और 65 लोगों ने इसे पसंदीदा के रूप में चिह्नित किया है। लगता है जैसे कि यह बहुत व्यापक है यह अभी भी एक बहुत अच्छा सवाल है।
अमीर

जवाबों:


171

मुझे एक प्रतिनिधि को "एक फ़ंक्शन के लिए एक संकेतक" के रूप में सोचना पसंद है। यह सी दिनों में वापस चला जाता है, लेकिन विचार अभी भी है।

विचार यह है कि आपको कोड का एक टुकड़ा आह्वान करने में सक्षम होना चाहिए, लेकिन आप जिस कोड को लागू करने जा रहे हैं, उस टुकड़े को रनटाइम तक नहीं जाना जाता है। तो आप उस उद्देश्य के लिए एक "प्रतिनिधि" का उपयोग करें। डेलिगेट्स इवेंट हैंडलर जैसी चीजों के लिए काम में आते हैं, और ऐसे, जहां आप विभिन्न घटनाओं के आधार पर अलग-अलग चीजें करते हैं, उदाहरण के लिए।

यहाँ सी # के लिए एक संदर्भ है आप देख सकते हैं:

उदाहरण के लिए, C # में, मान लें कि हमारे पास एक गणना थी जिसे हम करना चाहते थे और हम एक अलग गणना पद्धति का उपयोग करना चाहते थे जिसे हम रनटाइम के दौरान नहीं जानते हैं। तो हमारे पास कुछ गणना पद्धति हो सकती है:

public static double CalcTotalMethod1(double amt)
{
    return amt * .014;
}

public static double CalcTotalMethod2(double amt)
{
    return amt * .056 + 42.43;
}

हम इस तरह एक प्रतिनिधि हस्ताक्षर की घोषणा कर सकते हैं:

public delegate double calcTotalDelegate(double amt);

और फिर हम एक विधि की घोषणा कर सकते हैं जो प्रतिनिधि को इस तरह एक पैरामीटर के रूप में लेता है:

public static double CalcMyTotal(double amt, calcTotalDelegate calcTotal)
{
    return calcTotal(amt);
}

और हम CalcMyTotalजिस प्रतिनिधि पद्धति का उपयोग करना चाहते थे, उस पद्धति को हम कॉल कर सकते हैं।

double tot1 = CalcMyTotal(100.34, CalcTotalMethod1);
double tot2 = CalcMyTotal(100.34, CalcTotalMethod2);
Console.WriteLine(tot1);
Console.WriteLine(tot2);

19
सी। में सरल लेकिन प्रभावी फ़ंक्शन पॉइंटर के लिए +1
एडेन बेल

3
आपके उत्तर से संबंधित एक प्रश्न। यह वास्तव में सामान्य तरीके से किसी फ़ंक्शन को कॉल करने से कैसे भिन्न है? सिर्फ इसलिए कि यह रनटाइम पर ज्ञात नहीं है?
नवीद

1
@ नया - मेरे नवीनतम संपादन को देखें, मैंने एक उदाहरण शामिल किया। जहां तक ​​वास्तविक विधि कॉल की बात है, तो यह मेरे उदाहरण में एक सामान्य विधि कॉल से अलग नहीं दिखता है (कैल्कोटोटल (एमटी) प्रतिनिधि को बुला रहा है), लेकिन प्रतिनिधियों की शक्ति यह है कि आप उन्हें मापदंडों के रूप में उपयोग कर सकते हैं, आदि जब आप चाहते हैं कि एक विधि अलग व्यवहार करने में सक्षम हो। कई अन्य चीजें हैं जिनका उपयोग आप उनके लिए भी कर सकते हैं, यह सिर्फ एक सरल उदाहरण है। उम्मीद है की वो मदद करदे।
dcp

यह रनटाइम पर ज्ञात नहीं है, और एक नि: शुल्क फ़ंक्शन के बजाय एक बाध्य फ़ंक्शन है - Fooएक प्रतिनिधि को एक गैर-स्थिर विधि निर्दिष्ट करना this.Foo()एक स्थिर फ़ंक्शन के बजाय कॉल करेगा क्योंकि फ़ंक्शन पॉइंटर करेगा (सी में, आपके पास अक्सर एक अतिरिक्त void*पैरामीटर होता है thisसमारोह सूचक को पास )
पीट किर्कम

1
C / C ++ में फ़ंक्शन पॉइंटर्स के साथ समानताएं स्थापित करने वाले त्वरित और प्रभावी उदाहरण के लिए +1। बहुत सराहना की!
G21

19

एक प्रतिनिधि केवल एक फ़ंक्शन पॉइंटर है।
सीधे शब्दों में कहें कि आप अपने प्रतिनिधि को चलाने के लिए जिस विधि को चाहते हैं उसे सौंप दें। फिर बाद में कोड में आप इनवोक के माध्यम से उस विधि को कॉल कर सकते हैं।

प्रदर्शित करने के लिए कुछ कोड (इसे स्मृति से लिखा गया है, इसलिए वाक्य रचना बंद हो सकती है)

delegate void delMyDelegate(object o);

private void MethodToExecute1(object o)
{
    // do something with object
}

private void MethodToExecute2(object o)
{
    // do something else with object
}

private void DoSomethingToList(delMyDelegate methodToRun)
{
    foreach(object o in myList)
        methodToRun.Invoke(o);
}

public void ApplyMethodsToList()
{
    DoSomethingToList(MethodToExecute1);
    DoSomethingToList(MethodToExecute2);
}

16

यहां से ले गए

Q प्रतिनिधि क्या हैं?
A जब किसी वस्तु को एक अनुरोध प्राप्त होता है, तो वस्तु या तो अनुरोध को स्वयं संभाल सकती है या कार्य को करने के लिए अनुरोध को दूसरी वस्तु पर भेज सकती है। यदि ऑब्जेक्ट अनुरोध को पारित करने का निर्णय लेता है, तो आप कहते हैं कि ऑब्जेक्ट ने दूसरे ऑब्जेक्ट के लिए अनुरोध को संभालने के लिए जिम्मेदारी अग्रेषित की है।

या, एक आसान छद्म उदाहरण के रूप में: कुछ ऑब्जेक्ट 1 के लिए एक अनुरोध भेजता है। object1 फिर अनुरोध को और खुद object2 को - प्रतिनिधि को। ऑब्जेक्ट 2 अनुरोध को संसाधित करता है और कुछ काम करता है। (नोट: ऊपर दिया गया लिंक अच्छे उदाहरण देता है)


ऊपर दिए गए लिंक में दिया गया उदाहरण प्रतिनिधिमंडल को सही ढंग से नहीं बताता है।
हार्दिक 9850


4

एक प्रतिनिधि एक वस्तु है जो एक विधि को संदर्भित कर सकता है। इस प्रकार, जब हम एक प्रतिनिधि बनाते हैं, तो हम एक ऐसी वस्तु का निर्माण कर रहे हैं जो एक विधि का संदर्भ रख सकती है। इसके अलावा, विधि को इस संदर्भ के माध्यम से बुलाया जा सकता है। इस प्रकार, एक प्रतिनिधि उस पद्धति का आह्वान कर सकता है, जिसे वह संदर्भित करता है। एक प्रतिनिधि का मुख्य लाभ यह है कि यह हमें एक विधि को कॉल निर्दिष्ट करने की अनुमति देता है, लेकिन वास्तव में लागू विधि को निर्धारित समय पर नहीं, बल्कि रनटाइम पर निर्धारित किया जाता है।

सरल प्रतिनिधि

Declaration of delegate:
delegate-modifier delegate return-type delegate-name(parameters)
Implementation of delegate:
Delegate-name delegate-object=new Delegate-name(method of class)

http://knowpacific.wordpress.com/2012/01/26/delegate/


2

यहाँ मैं प्रतिनिधियों, बहुस्त्र्पीय प्रतिनिधियों और उनके उपयोग की व्याख्या करने जा रहा हूँ .. प्रतिनिधि एक प्रकार है जो किसी वस्तु में विधि (s) संदर्भ रखता है। इसे एक प्रकार का सुरक्षित फ़ंक्शन पॉइंटर भी कहा जाता है। हम कह सकते हैं कि एक प्रतिनिधि एक प्रकार है जो एक विधि हस्ताक्षर को परिभाषित करता है।

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

Delegates are like C++ function pointers but are type safe.
Delegates allow methods to be passed as parameters.
Delegates can be used to define callback methods.
Delegates can be chained together; for example, multiple methods can be called on a single event.
Methods do not have to match the delegate signature exactly.

जनता का प्रतिनिधि type_of_delegate प्रतिनिधिate_name () // घोषणा

You can use delegates without parameters or with parameter list
If you are referring to the method with some data type then the delegate which you are declaring should be in the same format. This is why it is referred to as type safe function pointer. Here I am giving an example with String.

निम्नलिखित उदाहरण एक प्रतिनिधि ऑपरेशन दिखाता है:

    namespace MyDelegate
    {
        class Program
        {
            private delegate void Show(string s);


            // Create a method for a delegate.
            public static void MyDelegateMethod(string me

ssage)
        {
            System.Console.WriteLine(message);
        }

        static void Main(string[] args)
        {
            Show p = MyDelegateMethod;
            p("My Delegate");
            p.Invoke("My Delegate");
            System.Console.ReadLine();
        }
    }
}

मल्टीकास्ट डेलिगेट क्या है?

यह एक प्रतिनिधि है जो एक से अधिक तरीकों का संदर्भ रखता है। मल्टीकास्ट प्रतिनिधियों में केवल विधियाँ होनी चाहिए जो शून्य लौटाती हैं, अन्यथा एक रन-टाइम अपवाद है।

 delegate void MyMulticastDelegate(int i, string s);
 Class Class2
 {
  static void MyFirstDelegateMethod(int i, string s)
  {
    Console.WriteLine("My First Method");
  }

  static void MySecondDelegateMethod(int i, string s)
  {
    Console.WriteLine("My Second Method");
  }

  static void Main(string[] args)
  {
    MyMulticastDelegate Method= new MyMulticastDelegate(MyFirstDelegateMethod);
    Method+= new MyMulticastDelegate (MySecondDelegateMethod);
    Method(1,"Hi");             // Calling 2 Methodscalled
    Method-= new MyMulticastDelegate (MyFirstDelegateMethod);
    Method(2,"Hi");             //Only 2nd Method calling
  }
}

यहां डेलिगेट + = ऑपरेटर का उपयोग करके जोड़ा जाता है और - = ऑपरेटर का उपयोग करके हटाया जाता है।

डेलिगेट प्रकार .NET फ्रेमवर्क में डेलिगेट वर्ग से लिए गए हैं। प्रतिनिधि प्रकार सील कर दिए गए हैं - वे व्युत्पन्न नहीं किए जा सकते हैं। क्योंकि तात्कालिक प्रतिनिधि एक वस्तु है, इसे एक पैरामीटर के रूप में पारित किया जा सकता है, या एक संपत्ति को सौंपा जा सकता है। यह एक प्रतिनिधि को एक पैरामीटर के रूप में स्वीकार करने के लिए एक विधि की अनुमति देता है, और कुछ बाद के समय में प्रतिनिधि को बुलाता है। यह एक अतुल्यकालिक कॉलबैक के रूप में जाना जाता है।


1

डेलिगेट पैटर्न का एक शानदार स्पष्टीकरण और व्यावहारिक कार्यान्वयन Google संग्रह अग्रेषण कक्षाएं (भी, सज्जाकार पैटर्न) में पाया जा सकता है ।


1

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

button1.Click + = new System.EventHandler (बटन1_Click) System.EventHandler यहां एक प्रतिनिधि के रूप में घोषित किया गया है। नेट इवेंट डेलिगेट की अवधारणा पर काम करते हैं (जैसे बटन क्लिक करें।

डेलीगेट का उपयोग तब किया जाता है जब आपको पता नहीं होता है कि रन टाइम में किस कोड को इनवाइट करना है।

http://msdn.microsoft.com/en-us/library/ms173171(v=vs.80).aspx


1

एक प्रतिनिधि वस्तु एक ऐसी वस्तु है जो उस वस्तु में कुछ होने पर एक अन्य वस्तु का संरक्षण करती है। उदाहरण के लिए, यदि आपकी कार के साथ कुछ होता है, तो आपका मरम्मत आदमी आपका प्रतिनिधि होता है। आप अपने मरम्मत आदमी के पास जाते हैं और उसे आपके लिए कार ठीक करने के लिए कहते हैं (हालांकि कुछ लोग खुद कार की मरम्मत करना पसंद करते हैं, इस स्थिति में, वे अपनी कार के लिए खुद के प्रतिनिधि हैं)।


1

एक प्रतिनिधि एक वस्तु है जो एक फ़ंक्शन के लिए सूचक का प्रतिनिधित्व करता है। हालाँकि, यह उस में एक सामान्य कार्य सूचक नहीं है:

1) ऑब्जेक्ट ओरिएंटेड है

2) प्रकार सुरक्षित है, अर्थात यह केवल एक विधि को इंगित कर सकता है और आप इसे इंगित करने वाले कच्चे मेमोरी पते को नहीं पढ़ सकते हैं

3) दृढ़ता से टाइप किया गया है। यह केवल उन तरीकों को इंगित कर सकता है जो इसके हस्ताक्षर से मेल खाते हैं।

4) एक ही समय में एक से अधिक तरीकों को इंगित कर सकता है।


1

डेलिगेट्स का उपयोग मुख्य रूप से घटनाओं के साथ किया जाता है।

जरूरत है:

जब आप प्रोग्राम चलाते हैं उस समय आप किसी कोड कोड को निष्पादित नहीं करना चाहते हैं। प्रोग्राम चलाने के बाद आप जब भी कोई घटना होती है तो उस कोड को निष्पादित करना चाहते हैं।

उदाहरण :

  1. सांत्वना आवेदन - कोड को प्रोग्राम चलाने के समय ही निष्पादित किया जा सकता है। (मुख्य विधि के अंदर लिखा)
  2. विंडोज एप्लिकेशन (यूजर इंटरफेस प्रोग्रामिंग) - प्रोग्राम को चलाने के बाद बटन क्लिक करने पर कोड निष्पादित किया जा सकता है।

यह वही है जो वे कहते हैं, आपको नहीं पता कि संकलन के समय कौन सी विधि लागू होगी। आप इसे केवल रनटाइम पर जानते हैं जो कि बटन पर क्लिक करते समय होता है।

प्रतिनिधियों के बिना कोई उपयोगकर्ता इंटरफ़ेस प्रोग्रामिंग संभव नहीं है। क्योंकि आप कोड को निष्पादित कर रहे हैं जब भी उपयोगकर्ता ईवेंट बनाता है जो बटन पर क्लिक कर रहा है, टेक्स्टबॉक्स में टाइप कर रहा है, ड्रॉपडेलिस्ट आइटम का चयन कर रहा है और इसी तरह…।


0

एक प्रतिनिधि एक ऐसा कार्य है जिसके लिए एक कार्य सौंपा जा रहा है। प्रतिनिधिमंडल का प्राथमिक उद्देश्य कोड को कम करना और अधिक लचीलेपन और पुन: उपयोग के लिए अनुमति देना है।

प्रोग्रामिंग, और विशेष रूप से ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग में, इसका मतलब है कि जब किसी कार्य को करने के लिए किसी विधि को बुलाया जाता है, तो वह उस कार्य को किसी अन्य ऑब्जेक्ट की विधि को पास करता है जिसके पास इसका संदर्भ है। जब तक हम जिस वस्तु की इच्छा करते हैं, वह संदर्भ इंगित कर सकती है, जब तक कि वस्तु विधियों के पूर्वनिर्धारित सेट के अनुरूप हो। हम इसे "एक इंटरफेस के लिए प्रोग्रामिंग" (एक ठोस वर्ग कार्यान्वयन के लिए प्रोग्रामिंग) कहते हैं। एक इंटरफ़ेस मूल रूप से एक सामान्य टेम्पलेट है और इसका कोई कार्यान्वयन नहीं है; इसका सीधा मतलब है एक नुस्खा, तरीकों का एक सेट, पूर्व शर्त और पोस्टकंडिशन (नियम)।

सरल उदाहरण:

SomeInterface
{
   public void doSomething();
}


SomeImplementation implements SomeInterface
{
   public void doSomething()
   {
      System.err.println("Was it good for you?");
   }

}


SomeCaller
{
   public void doIt(SomeInterface someInterface)
   {
      someInterface.doSomething();
   }
}

अब आप देखते हैं कि मैं किसी भी समय कुछ भी कार्यान्वयन का उपयोग कर सकते हैं, कुछ कोडरेलर में कोड को बदले बिना, क्योंकि जो प्रकार doIt()पारित किया गया है वह ठोस नहीं है, बल्कि सार है क्योंकि यह एक इंटरफ़ेस है। जावा दुनिया में, यह अक्सर सेवा प्रतिमान में व्यक्त किया जाता है जहां आप एक सेवा (एक विशिष्ट इंटरफ़ेस के माध्यम से एक सेवा के रूप में एक वस्तु विज्ञापन) और सेवा को कॉल करते हैं और फिर प्रतिनिधियों को कॉल करके इसे अपना काम करने में मदद करते हैं। सेवा के तरीकों को मोटे-दाने वाले कार्यों (मेकपायमेंट (), createNewUser (), आदि) के रूप में नामित किया गया है, जबकि आंतरिक रूप से यह बहुत कुछ करता है यदि प्रतिनिधि के माध्यम से निटी-किरकिरा काम करते हैं, तो प्रतिनिधियों के प्रकार ठोस कार्यान्वयन के बजाय इंटरफेस हैं।

SomeService
{
    SomeInterface someImplementation = ... // assign here
    SomeOtherInterface someOtherImplementation = ... // okay, let's add a second

    public void doSomeWork()
    {
         someImplementation.doSomething();
         someOtherImplementation.doSomethingElse();
    }
}

(एनबी: एक कार्यान्वयन कैसे सौंपा जाता है यह इस धागे के दायरे से परे है। नियंत्रण और निर्भरता इंजेक्शन का लुकअप उलटा।)


-2

हालांकि वास्तव में "फ़ंक्शन पॉइंटर" नहीं है, एक प्रतिनिधि ऐसा लग सकता है जैसे यह एक गतिशील भाषा है जैसे कि PHP:



$func = 'foo';
$func();

function foo() {
    print 'foo';
}

या जावास्क्रिप्ट में आप ऐसा कुछ कर सकते हैं:


var func = function(){ alert('foo!'); }
func();


2
यह प्रतिनिधिमंडल का उदाहरण नहीं है। आपके उदाहरण में, आप वह प्रयोग कर रहे हैं जिसे एक चर फ़ंक्शन कहा जाता है जो मूल रूप से एक फ़ंक्शन के लिए दिखता है जिसका नाम उसी स्ट्रिंग के समान है जिसे एक चर संदर्भित करता है। चर कार्य देखें: php.net/manual/en/functions.variable-functions.php
Aquarelle
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.