C # में घटनाओं और घटना संचालकों को समझना


329

मैं विशेष रूप से उपयोगकर्ता इंटरफ़ेस बनाने के संदर्भ में घटनाओं के उद्देश्य को समझता हूं। मुझे लगता है कि यह एक घटना बनाने का प्रोटोटाइप है:

public void EventName(object sender, EventArgs e);

ईवेंट हैंडलर क्या करते हैं, उनकी आवश्यकता क्यों है, और मैं एक कैसे बना सकता हूं?


9
जैसा कि @Andy द्वारा उल्लेख किया गया है, यहां कोड स्निपेट घटना में पंजीकृत विधि का वर्णन करता है, न कि घटना का।
दशरथ


जवाबों:


660

घटना संचालकों को समझने के लिए, आपको प्रतिनिधियों को समझने की आवश्यकता है । में सी # , आप एक विधि के लिए एक सूचक (या एक संदर्भ) के रूप में एक प्रतिनिधि के बारे में सोच सकते हैं। यह उपयोगी है क्योंकि सूचक को मूल्य के रूप में चारों ओर पारित किया जा सकता है।

एक प्रतिनिधि की केंद्रीय अवधारणा उसके हस्ताक्षर, या आकार है। वह (1) रिटर्न प्रकार और (2) इनपुट तर्क हैं। उदाहरण के लिए, अगर हम एक प्रतिनिधि बनाने void MyDelegate(object sender, EventArgs e), यह केवल तरीकों जो बदले को इंगित कर सकते हैं void, और एक ले objectऔर EventArgs। एक वर्ग छेद और एक वर्ग खूंटी की तरह। तो हम कहते हैं कि इन विधियों में प्रतिनिधि के रूप में एक ही हस्ताक्षर, या आकृति है।

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

तो डिफ़ॉल्ट EventHandler(और कई इसे पसंद) विधि के एक विशिष्ट आकार का प्रतिनिधित्व करता है (फिर से, शून्य / वस्तु- EventArgs)। जब आप किसी घटना की घोषणा करते हैं, तो आप कह रहे हैं कि कौन सा आकार (EventHandler) उस घटना को आमंत्रित करेगा, एक प्रतिनिधि को निर्दिष्ट करके:

//This delegate can be used to point to methods
//which return void and take a string.
public delegate void MyEventHandler(string foo);

//This event can cause any method which conforms
//to MyEventHandler to be called.
public event MyEventHandler SomethingHappened;

//Here is some code I want to be executed
//when SomethingHappened fires.
void HandleSomethingHappened(string foo)
{
    //Do some stuff
}

//I am creating a delegate (pointer) to HandleSomethingHappened
//and adding it to SomethingHappened's list of "Event Handlers".
myObj.SomethingHappened += new MyEventHandler(HandleSomethingHappened);

//To raise the event within a method.
SomethingHappened("bar");

(* यह .NET में घटनाओं की कुंजी है और "जादू" को छील देता है - एक घटना वास्तव में है, कवर के तहत, उसी "आकार" के तरीकों की एक सूची है। वह सूची संग्रहीत है जहां घटना रहती है। घटना "बढ़ा हुआ" है, यह वास्तव में सिर्फ "विधियों की इस सूची के माध्यम से जाना है और हर एक को कॉल करें, इन मानों को मापदंडों के रूप में उपयोग करें"। एक घटना हैंडलर को सौंपना सिर्फ एक उपदेशक है, तरीकों की इस सूची में अपना तरीका जोड़ने का आसान तरीका कहा जा सकता है)।


24
और अब कोई समझा सकता है कि इस घटना को EventHandler क्यों कहा जाता है ?? सभी भ्रामक नामकरण सम्मेलनों में, यह सबसे बुरा है ...
जोएल में Gö

37
@Joel in Go इवेंट को इवेंटहैंडलर नहीं कहा जाता है - ईवेंटहैंडलर वह अनुबंध है, जिसके साथ ईवेंट किसी के पास होना चाहिए जो इसके साथ संचार करता है। यह "स्ट्रिंग मायस्ट्रिंग" जैसा है - स्ट्रिंग प्रकार की घोषणा कर रहा है। ईवेंट MyEventHandler TheEvent यह घोषणा कर रहा है कि जो कोई भी इस ईवेंट के साथ सहभागिता करता है, उसे MyEventHandler अनुबंध के अनुरूप होना चाहिए। हैंडलर सम्मेलन इसलिए है क्योंकि अनुबंध मुख्य रूप से वर्णन करता है कि घटना को कैसे संभालना है।
रेक्स एम

18
कैसे हुई घटना?
रसायन विज्ञान

17
@ आरएक्स एम: "मायएवेंटहैंडलर" के लिए पहले सुसंगत स्पष्टीकरण के लिए धन्यवाद जो मैंने कभी देखा है :)
जोएल इन जीओ

10
चरण के लिए धन्यवाद: "घटना और निष्पादित करने के तरीकों के बीच गोंद प्रतिनिधि हैं।", यह वास्तव में बहुत बढ़िया है।
जियोनी

103

C # दो शब्द जानता है, delegateऔर event। पहले वाले से शुरू करते हैं।

प्रतिनिधि

A delegateएक विधि का संदर्भ है। जैसे आप एक उदाहरण के लिए एक संदर्भ बना सकते हैं:

MyClass instance = myFactory.GetInstance();

आप किसी प्रतिनिधि को विधि का संदर्भ बनाने के लिए उपयोग कर सकते हैं:

Action myMethod = myFactory.GetInstance;

अब जब आपके पास एक विधि का संदर्भ है, तो आप संदर्भ के माध्यम से विधि को कॉल कर सकते हैं:

MyClass instance = myMethod();

लेकिन तुम क्यों करोगे? आप myFactory.GetInstance()सीधे कॉल भी कर सकते हैं। इस मामले में आप कर सकते हैं। हालाँकि, इस बारे में सोचने के लिए कई मामले हैं कि आप नहीं चाहते कि बाकी एप्लिकेशन को सीधे ज्ञान हो myFactoryया myFactory.GetInstance()सीधे कॉल करना हो।

एक स्पष्ट एक अगर आप को बदलने के लिए सक्षम होना चाहते हैं है myFactory.GetInstance()में myOfflineFakeFactory.GetInstance()एक केंद्रीय स्थान (उर्फ से कारखाने विधि पैटर्न )।

फैक्टरी विधि पैटर्न

इसलिए, यदि आपके पास एक TheOtherClassवर्ग है और उसे इसका उपयोग करने की आवश्यकता है myFactory.GetInstance(), तो यह है कि प्रतिनिधि के बिना कोड कैसा दिखेगा (आपको अपने TheOtherClassप्रकार के बारे में बताने की आवश्यकता होगी myFactory):

TheOtherClass toc;
//...
toc.SetFactory(myFactory);


class TheOtherClass
{
   public void SetFactory(MyFactory factory)
   {
      // set here
   }

}

यदि आप प्रतिनिधियों का उपयोग करेंगे, तो आपको मेरे कारखाने के प्रकार को उजागर करने की आवश्यकता नहीं है:

TheOtherClass toc;
//...
Action factoryMethod = myFactory.GetInstance;
toc.SetFactoryMethod(factoryMethod);


class TheOtherClass
{
   public void SetFactoryMethod(Action factoryMethod)
   {
      // set here
   }

}

इस प्रकार, आप अपने प्रकार को उजागर किए बिना, किसी अन्य वर्ग को उपयोग करने के लिए एक प्रतिनिधि दे सकते हैं। केवल एक चीज जो आप उजागर कर रहे हैं, वह है आपके तरीके का हस्ताक्षर (आपके पास कितने पैरामीटर हैं और ऐसे)।

"मेरी पद्धति का हस्ताक्षर", मैंने पहले कहां सुना था? ओ हाँ, इंटरफेस !!! इंटरफेस एक पूरे वर्ग के हस्ताक्षर का वर्णन करते हैं। केवल एक विधि के हस्ताक्षर का वर्णन करने के रूप में प्रतिनिधियों के बारे में सोचो!

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

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

एक के लिए प्रतिबंध MulticastDelegateकि (विधि / प्रतिनिधि) हस्ताक्षर किसी भी वापसी मान (नहीं होना चाहिए रहे हैं void) और कीवर्ड्स outऔर refहस्ताक्षर में नहीं किया जाता है। जाहिर है, आप दो तरीकों को कॉल नहीं कर सकते हैं जो एक नंबर लौटाते हैं और उनसे उसी नंबर को वापस करने की अपेक्षा करते हैं। हस्ताक्षर के अनुपालन के बाद, प्रतिनिधि स्वचालित रूप से एक है MulticastDelegate

प्रतिस्पर्धा

घटनाएँ सिर्फ गुण हैं (जैसे; सेट; गुण उदाहरण क्षेत्रों के लिए) जो अन्य वस्तुओं से प्रतिनिधि को सदस्यता को उजागर करते हैं। हालांकि, इन गुणों का समर्थन नहीं मिलता है; इसके बजाय, वे जोड़ने का समर्थन करते हैं; हटाना;

तो आपके पास हो सकता है:

    Action myField;

    public event Action MyProperty
    {
        add { myField += value; }
        remove { myField -= value; }
    }

UI में उपयोग (WinForms, WPF, UWP इत्यादि)

तो, अब हम जानते हैं कि एक प्रतिनिधि एक विधि का एक संदर्भ है और हमें दुनिया को यह बताने के लिए एक घटना हो सकती है कि वे हमें हमारे प्रतिनिधि से संदर्भित होने के लिए अपने तरीके दे सकते हैं, और हम एक यूआई बटन हैं, फिर: हम किसी से भी पूछ सकते हैं कि क्या मुझे क्लिक करने में दिलचस्पी है, हमारे साथ अपनी विधि दर्ज करने के लिए (जिस घटना को हमने उजागर किया है)। हम उन सभी तरीकों का उपयोग कर सकते हैं जो हमें दिए गए थे और हमारे प्रतिनिधि द्वारा उनका संदर्भ दिया गया था। और फिर, हम प्रतीक्षा करेंगे और प्रतीक्षा करेंगे .... जब तक कोई उपयोगकर्ता नहीं आता है और उस बटन पर क्लिक करता है, तब तक हमारे पास प्रतिनिधि को आमंत्रित करने के लिए पर्याप्त कारण होगा। और क्योंकि प्रतिनिधि हमें दिए गए उन सभी तरीकों का संदर्भ देते हैं, उन सभी तरीकों को लागू किया जाएगा। हमें नहीं पता कि वे तरीके क्या करते हैं, और न ही हमें पता है कि कौन सी कक्षा उन तरीकों को लागू करती है। हम सभी इस बात की परवाह करते हैं कि किसी को क्लिक करने में हमारी दिलचस्पी थी,

जावा

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


स्पष्टीकरण के लिए चीयर्स लेकिन एक घटना कैसे एक प्रतिनिधि के उदाहरण से अलग होती है जो ग्राहकों को लेता है? वे दोनों बिल्कुल एक जैसे दिखते हैं?
बीकेएसपूर्जन

@BKSpurgeon है कि क्योंकि वे कर रहे हैं "प्रतिनिधियों कि ग्राहकों पर ले" - eventमात्र वाक्य रचना चीनी, ज्यादा कुछ नहीं है।
मैथ्यू गुइंडन

"मल्टीकास्टडेगेट के लिए प्रतिबंध यह है कि विधि (प्रतिनिधि / प्रतिनिधि) हस्ताक्षर का कोई वापसी मूल्य (शून्य) नहीं होना चाहिए", मुझे नहीं लगता कि यह सही है। यदि उनके पास रिटर्न मान हैं, तो यह पिछले एक को लौटा देगा।
होजिकमारु

"इस प्रकार, आप अपने प्रकार को उजागर किए बिना, किसी अन्य वर्ग को उपयोग करने के लिए एक प्रतिनिधि दे सकते हैं। केवल एक चीज जिसे आप उजागर कर रहे हैं, वह है आपके तरीके का हस्ताक्षर ..." - मेरे लिए यह महत्वपूर्ण बिंदु है। धन्यवाद!
रयान

40

यह वास्तव में एक घटना हैंडलर के लिए घोषणा है - एक विधि जिसे किसी घटना के निकाल दिए जाने पर कहा जाएगा। एक ईवेंट बनाने के लिए, आप कुछ इस तरह से लिखेंगे:

public class Foo
{
    public event EventHandler MyEvent;
}

और फिर आप इस तरह की घटना के लिए सदस्यता ले सकते हैं:

Foo foo = new Foo();
foo.MyEvent += new EventHandler(this.OnMyEvent);

OnMyEvent () को इस तरह परिभाषित किया गया है:

private void OnMyEvent(object sender, EventArgs e)
{
    MessageBox.Show("MyEvent fired!");
}

जब भी Fooआग बुझाई जाएगी MyEvent, तब आपके OnMyEventहैंडलर को बुलाया जाएगा।

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


14
सवाल का जवाब देने और डेलिगेट्स और इवेंट्स में नहीं जाने के लिए धन्यवाद।
divide_byzero

3
मैं OnXXXआपके ईवेंट हैंडलर के नामकरण पैटर्न का उपयोग करने के खिलाफ सलाह दूंगा। (Stupidly, OnXXX का अर्थ MFC में 'XXX को संभालना', और 'XXX को उठाना', 'innet' से लिया गया है, और इसलिए अब इसका अर्थ अस्पष्ट और भ्रमित है - विवरण के लिए इस पोस्ट को देखें )। पसंदीदा नाम RaiseXXXघटनाओं को बढ़ाने के लिए, HandleXXXया Sender_XXXघटना संचालकों के लिए होगा।
जेसन विलियम्स

1
क्या आप एक साधारण WinForms एप्लिकेशन के साथ काम करने का उदाहरण दिखा सकते हैं?
219 बजे MC9000

40

यहाँ एक कोड उदाहरण है जो मदद कर सकता है:

using System;
using System.Collections.Generic;
using System.Text;

namespace Event_Example
{
  // First we have to define a delegate that acts as a signature for the
  // function that is ultimately called when the event is triggered.
  // You will notice that the second parameter is of MyEventArgs type.
  // This object will contain information about the triggered event.

  public delegate void MyEventHandler(object source, MyEventArgs e);

  // This is a class which describes the event to the class that receives it.
  // An EventArgs class must always derive from System.EventArgs.

  public class MyEventArgs : EventArgs
  {
    private string EventInfo;

    public MyEventArgs(string Text) {
      EventInfo = Text;
    }

    public string GetInfo() {
      return EventInfo;
    }
  }

  // This next class is the one which contains an event and triggers it
  // once an action is performed. For example, lets trigger this event
  // once a variable is incremented over a particular value. Notice the
  // event uses the MyEventHandler delegate to create a signature
  // for the called function.

  public class MyClass
  {
    public event MyEventHandler OnMaximum;

    private int i;
    private int Maximum = 10;

    public int MyValue
    {
      get { return i; }
      set
      {
        if(value <= Maximum) {
          i = value;
        }
        else 
        {
          // To make sure we only trigger the event if a handler is present
          // we check the event to make sure it's not null.
          if(OnMaximum != null) {
            OnMaximum(this, new MyEventArgs("You've entered " +
              value.ToString() +
              ", but the maximum is " +
              Maximum.ToString()));
          }
        }
      }
    }
  }

  class Program
  {
    // This is the actual method that will be assigned to the event handler
    // within the above class. This is where we perform an action once the
    // event has been triggered.

    static void MaximumReached(object source, MyEventArgs e) {
      Console.WriteLine(e.GetInfo());
    }

    static void Main(string[] args) {
      // Now lets test the event contained in the above class.
      MyClass MyObject = new MyClass();
      MyObject.OnMaximum += new MyEventHandler(MaximumReached);
      for(int x = 0; x <= 15; x++) {
        MyObject.MyValue = x;
      }
      Console.ReadLine();
    }
  }
}

4
सी # 6 में प्रतिनिधि आह्वान को सरल बनाया जा सकता है:OnMaximum?.Invoke(this,new MyEventArgs("you've entered..."));
टिम श्मेल्टर

23

यहाँ मौजूदा महान उत्तरों को जोड़ने के लिए - स्वीकृत एक में कोड पर निर्माण, जो एक का उपयोग करता है delegate void MyEventHandler(string foo)...

क्योंकि कंपाइलर सम्‍मिलित प्रकार के SomeHappened ईवेंट को जानता है , यह:

myObj.SomethingHappened += HandleSomethingHappened;

के बराबर है:

myObj.SomethingHappened += new MyEventHandler(HandleSomethingHappened);

और संचालकों को भी हो सकता है अपंजीकृत साथ -=इस तरह:

// -= removes the handler from the event's list of "listeners":
myObj.SomethingHappened -= HandleSomethingHappened;

पूर्णता के लिए, घटना को इस तरह से पूरा किया जा सकता है, केवल उस वर्ग में जो इस घटना का मालिक है:

//Firing the event is done by simply providing the arguments to the event:
var handler = SomethingHappened; // thread-local copy of the event
if (handler != null) // the event is null if there are no listeners!
{
    handler("Hi there!");
}

हैंडलर के धागे की स्थानीय प्रतिलिपि बनाने के लिए की जरूरत है सुनिश्चित करें कि मंगलाचरण धागा सुरक्षित है - अन्यथा एक धागा जाने के लिए और कर सकता है घटना के लिए पिछले हैंडलर के तुरंत बाद हम अगर यह था की जाँच की अपंजीकृत null, और हम एक "मजा" के लिए होता है NullReferenceExceptionवहाँ ।


C # 6 ने इस पैटर्न के लिए एक अच्छा शॉर्ट हैंड पेश किया। यह अशक्त प्रसार संचालक का उपयोग करता है।

SomethingHappened?.Invoke("Hi there!");

13

घटनाओं के बारे में मेरी समझ है;

प्रतिनिधि:

निष्पादित करने के लिए विधि / विधियों के संदर्भ में एक चर। यह एक चर की तरह तरीकों के आसपास से गुजरना संभव बनाता है।

ईवेंट बनाने और कॉल करने के चरण:

  1. घटना एक प्रतिनिधि का एक उदाहरण है

  2. चूंकि एक घटना एक प्रतिनिधि का एक उदाहरण है, तो हमें पहले प्रतिनिधि को परिभाषित करना होगा।

  3. ईवेंट को निकाल दिए जाने पर निष्पादित किए जाने वाले तरीके / विधियों को असाइन करें ( प्रतिनिधि को कॉल करना )

  4. घटना को फायर करें ( प्रतिनिधि को बुलाएं )

उदाहरण:

using System;

namespace test{
    class MyTestApp{
        //The Event Handler declaration
        public delegate void EventHandler();

        //The Event declaration
        public event EventHandler MyHandler;

        //The method to call
        public void Hello(){
            Console.WriteLine("Hello World of events!");
        }

        public static void Main(){
            MyTestApp TestApp = new MyTestApp();

            //Assign the method to be called when the event is fired
            TestApp.MyHandler = new EventHandler(TestApp.Hello);

            //Firing the event
            if (TestApp.MyHandler != null){
                TestApp.MyHandler();
            }
        }

    }   

}

3

प्रकाशक: जहां घटनाएं होती हैं। प्रकाशक को यह निर्दिष्ट करना चाहिए कि वर्ग किस प्रतिनिधि का उपयोग कर रहा है और आवश्यक तर्क उत्पन्न कर रहा है, उन तर्कों को और स्वयं प्रतिनिधि को पास करें।

ग्राहक: जहां प्रतिक्रिया होती है। सब्सक्राइबर को घटनाओं पर प्रतिक्रिया करने के लिए तरीके निर्दिष्ट करने चाहिए। इन तरीकों को प्रतिनिधि के रूप में एक ही प्रकार के तर्क लेने चाहिए। सब्सक्राइबर फिर इस विधि को प्रकाशक के प्रतिनिधि में जोड़ें।

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


2
//This delegate can be used to point to methods
//which return void and take a string.
public delegate void MyDelegate(string foo);

//This event can cause any method which conforms
//to MyEventHandler to be called.
public event MyDelegate MyEvent;

//Here is some code I want to be executed
//when SomethingHappened fires.
void MyEventHandler(string foo)
{
    //Do some stuff
}

//I am creating a delegate (pointer) to HandleSomethingHappened
//and adding it to SomethingHappened's list of "Event Handlers".
myObj.MyEvent += new MyDelegate (MyEventHandler);

0

मैं KE50 से सहमत हूं, सिवाय इसके कि मैं 'ईवेंट' कीवर्ड को 'ActionCollection' के लिए एक उपनाम के रूप में देखता हूं, क्योंकि ईवेंट प्रदर्शन किए जाने वाले कार्यों का एक संग्रह रखता है (यानी प्रतिनिधि)।

using System;

namespace test{

class MyTestApp{
    //The Event Handler declaration
    public delegate void EventAction();

    //The Event Action Collection 
    //Equivalent to 
    //  public List<EventAction> EventActions=new List<EventAction>();
    //        
    public event EventAction EventActions;

    //An Action
    public void Hello(){
        Console.WriteLine("Hello World of events!");
    }
    //Another Action
    public void Goodbye(){
        Console.WriteLine("Goodbye Cruel World of events!");
    }

    public static void Main(){
        MyTestApp TestApp = new MyTestApp();

        //Add actions to the collection
        TestApp.EventActions += TestApp.Hello;
        TestApp.EventActions += TestApp.Goodbye;

        //Invoke all event actions
        if (TestApp.EventActions!= null){
            //this peculiar syntax hides the invoke 
            TestApp.EventActions();
            //using the 'ActionCollection' idea:
            // foreach(EventAction action in TestApp.EventActions)
            //     action.Invoke();
        }
    }

}   

}

0

पोस्ट में शानदार तकनीकी जवाब! मेरे पास इसमें जोड़ने के लिए तकनीकी रूप से कुछ भी नहीं है।

मुख्य कारणों में से एक यह है कि सामान्य रूप से भाषाओं और सॉफ़्टवेयर में नई विशेषताएं विपणन या कंपनी की राजनीति क्यों हैं! :-) यह अनुमान के तहत नहीं होना चाहिए!

मुझे लगता है कि यह प्रतिनिधियों और घटनाओं के लिए कुछ हद तक लागू होता है! मैं उन्हें उपयोगी पाता हूं और C # भाषा में मूल्य जोड़ता हूं, लेकिन दूसरी ओर जावा भाषा ने उनका उपयोग नहीं करने का फैसला किया! उन्होंने फैसला किया कि आप जो कुछ भी प्रतिनिधियों के साथ हल कर रहे हैं, आप पहले से ही भाषा की मौजूदा विशेषताओं के साथ हल कर सकते हैं अर्थात इंटरफेस

अब लगभग 2001 में Microsoft ने .NET फ्रेमवर्क और C # भाषा को जावा के एक प्रतियोगी समाधान के रूप में जारी किया, इसलिए नए फीचर्स का होना अच्छा था जो जावा के पास नहीं है।


0

मैंने हाल ही में c # में घटनाओं का उपयोग करने का एक उदाहरण बनाया, और इसे अपने ब्लॉग पर पोस्ट किया। मैंने इसे बहुत सरल उदाहरण के साथ यथासंभव स्पष्ट करने की कोशिश की। मामले में यह किसी की मदद कर सकता है, यहाँ यह है: http://www.konsfik.com/using-events-in-csharp/

इसमें विवरण और स्रोत कोड (बहुत सारी टिप्पणियों के साथ) शामिल हैं, और यह मुख्य रूप से घटनाओं और इवेंट हैंडलर्स के एक उचित (टेम्पलेट - जैसे) उपयोग पर केंद्रित है।

कुछ मुख्य बिंदु हैं:

  • घटनाएँ "उप-प्रकार के प्रतिनिधियों" की तरह हैं, केवल अधिक विवश (अच्छे तरीके से)। वास्तव में एक घटना की घोषणा में हमेशा एक प्रतिनिधि शामिल होता है (EventHandlers एक प्रकार का प्रतिनिधि होता है)।

  • ईवेंट हैंडलर विशिष्ट प्रकार के प्रतिनिधि हैं (आप उन्हें एक टेम्पलेट के रूप में सोच सकते हैं), जो उपयोगकर्ता को एक विशिष्ट "हस्ताक्षर" बनाने के लिए मजबूर करते हैं। हस्ताक्षर प्रारूप का है: (ऑब्जेक्ट प्रेषक, EventArgs eventarguments)।

  • आप किसी भी प्रकार की जानकारी को शामिल करने के लिए अपने स्वयं के EventArgs का अपना उप-वर्ग बना सकते हैं, जिसमें घटना को व्यक्त करने की आवश्यकता होती है। घटनाओं का उपयोग करते समय EventHandlers का उपयोग करना आवश्यक नहीं है। आप उन्हें पूरी तरह से छोड़ सकते हैं और उनके स्थान पर अपनी तरह के प्रतिनिधि का उपयोग कर सकते हैं।

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


0

एक और बात के बारे में जानने के लिए , कुछ मामलों में, आपको कम स्तर के युग्मन की आवश्यकता होने पर डेलिगेट्स / ईवेंट का उपयोग करना होगा !

यदि आप आवेदन में कई जगह एक घटक का उपयोग करना चाहते हैं , तो आपको कपलिंग के निम्न स्तर के साथ एक घटक बनाने की आवश्यकता होती है और विशिष्ट असंबद्ध लोगो को आपके घटक का प्रतिनिधि होना चाहिए ! यह सुनिश्चित करता है कि आपके पास एक डिकोड्ड सिस्टम और एक क्लीनर कोड है।

में ठोस सिद्धांत यह है " डी ", ( डी ependency उलट सिद्धांत)।

" आईओसी " के रूप में भी जाना जाता है , नियंत्रण का उलटा

आप इवेंट्स, डेलिगेट्स और DI (डिपेंडेंसी इंजेक्शन) के साथ " IoC " बना सकते हैं ।

बाल वर्ग में एक विधि तक पहुंचना आसान है। लेकिन बच्चे से माता-पिता वर्ग में एक विधि का उपयोग करना अधिक कठिन है। आपको बच्चे के माता-पिता के संदर्भ को पास करना होगा! (या इंटरफ़ेस के साथ DI का उपयोग करें)

प्रतिनिधि / ईवेंट हमें बिना संदर्भ के बच्चे से माता-पिता तक संवाद करने की अनुमति देते हैं!

यहां छवि विवरण दर्ज करें

ऊपर दिए गए इस आरेख में, मैं डेलिगेट / ईवेंट का उपयोग नहीं करता हूं और मूल घटक B के पास ए (विधि के उच्च स्तर के युग्मन) में असंबद्ध व्यापार तर्क को निष्पादित करने के लिए मूल घटक A का संदर्भ है।

इस दृष्टिकोण के साथ, मुझे सभी घटकों के सभी संदर्भों को रखना होगा जो घटक बी का उपयोग करते हैं! :(

यहां छवि विवरण दर्ज करें

ऊपर दिए गए इस आरेख में, मैं डेलिगेट / ईवेंट का उपयोग करता हूं और घटक B को ज्ञात A. (युग्मन का निम्न स्तर) नहीं है

और आप अपने आवेदन में कहीं भी अपने घटक बी का उपयोग कर सकते हैं !

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.