Quick understanding of delegates and events in C #

Source: Internet
Author: User
Tags getmessage new set

The following is a personal understanding and is for informational purposes only.

what is a delegate.

First look at the simplest example of a delegate:

Namespace DelegateTest
{public
    delegate void Messagedelegate (string name);
    Class program
    {
        private static void SaySomething (string name)
        {
            Console.WriteLine ("Your said" + name); c9/>}
        static void Main (string[] args)
        {
            messagedelegate msgdelegate = new Messagedelegate (saysomething );
            Msgdelegate ("Hello");
            Console.readkey ();}}

The output is: you said Hello

From the code we can see that saysomething is a method, delegate is a class.

In layman's terms, a delegate is a container for a method, just as an array string[] is a container for a string variable.

A delegate object that returns the value void type and receives a string type parameter can only bind the same type of method.

Messagedelegate msgdelegate = new Messagedelegate (saysomething);

This code is the initialization of the delegate object, we put saysomething this method into the msgdelegate.

Its construction method must have 1 methods as parameters in order to initialize.

Initializing a delegate object can also directly assign a method to initialize, such as:

Messagedelegate msgdelegate=saysomething;

This time the SaySomething method has been loaded into the delegate object Msgdelegate, so you can invoke the loaded method by calling the delegate object.

We call the delegate object Msgdelegate as a method when we want to use it.

Process Summary:

1. Define delegate objects

public delegate void Messagedelegate (string name);

2. Definition method

private static void SaySomething (string name)

{

Console.WriteLine ("You said" + name);

}

3. Create a new delegate object and initialize it

Messagedelegate msgdelegate = new Messagedelegate (saysomething);

Or

Messagedelegate msgdelegate=saysomething;

4. Invoke Delegate Object

Msgdelegate ("Hello");

The above is a delegate without a return value, and if the delegate to bring the return value can make its own:

public delegate int Addnumber (int a,int b);

  static void Main (string[] args)
        {
            addnumber an= new Addnumber (MyFunc);
           Int N=an (1,2);
Console.WriteLine (n);
           Console.readkey ();
        }
  private static int Addfunc (int a,int b)
        {return
            a+b;        
}

Multicast Delegate:

If the delegate object is a container, that delegate object can bind multiple methods.

Quite simply, we use + + to bind more objects.

Instead, we can use-= to unbind the object.


Namespace DelegateTest
{

    class program
    {public
        delegate void Messagedelegate (string name);
        private static void SaySomething (string name)
        {
            Console.WriteLine ("You said" + name);
        }
        private static void Sayanything (String str)
        {
            Console.WriteLine (str);
        }
        static void Main (string[] args)
        {
            messagedelegate msgdelegate = new Messagedelegate (saysomething);
            Msgdelegate + = sayanything;
            Msgdelegate ("Meh");
            Console.readkey ();}}

The output results are:

You said Meh

Meh

Note: The list of delegate objects cannot be called when it is empty (null), but you can bind or Unbind objects.

Since the delegate object is a class, we can also pass the delegate object as a parameter to a method.

Namespace DelegateTest
{

    class program
    {public
        delegate void Messagedelegate (string name);
        private static void SaySomething (string name)
        {
            Console.WriteLine ("You said" + name);
        }
           private static void Sayanything (Messagedelegate msgdelegate)
        {
            if (msgdelegate!=null)
            msgdelegate (" Hello ");
        }

        static void Main (string[] args)
        {
            messagedelegate msgdelegate = new Messagedelegate (saysomething);
            Sayanything (msgdelegate);
            Sayanything (saysomething);
            Msgdelegate.invoke ("xxx");
            Msgdelegate ("xxx");
            Console.readkey ();}}

The output results are:

You said Hello

You said Hello

Xxx

Xxx

We call it in 4 different ways, the first is to pass in a delegate object, the second is the incoming method, the third is to call the delegate directly, and the fourth and third are equivalent.

It can be seen from this that we can pass the method as a parameter to a delegate object type to invoke, or you can pass a delegate type with the method as a parameter after the call.

Summary:

A delegate object is a class that can pass the same method as the return value and parameters of a delegate object, and then call it.

Delegates can bind multiple methods and call them sequentially.

A delegate is a function pointer, and the primary function is to implement communication and callbacks between classes, just as you entrust a friend to do something for you, your friend will tell you the progress.

Why should I use a delegate? When to use a delegate.

Looking at the example above, most of the students should have a understanding of the delegation, there may be alumni asked why not directly call saysomething and to be indirectly through the delegation of the delegate object, what is the benefit of the Commission, when it should be commissioned, in fact, literally commissioned the meaning of the two-party communication intermediary, For example, Chinese and Russian exchanges need to be commissioned to achieve the translation, and then we look at a few examples.

First, when you are not sure how to use the specific method

For example, you are a kindergarten teacher, you want to reward children food, have the following several rewards:

private static void Givelolipop ()
        {
            //gives Lollipop
            Console.WriteLine ("Lollipop");
        }
        private static void Givecake ()
        {
            //gave the cake
            Console.WriteLine ("To the Cake");
        }
        private static void Givesugar ()
        {
            //gave Candy
            Console.WriteLine ("Candy");
        }
        The private static void Givebiscuit ()
        {
            //gave the cookie
            Console.WriteLine ("Cookies");
        }

If we want to tailor a set of rewards to each child, you can define multiple methods to implement

  private static void GiveChildren1 ()
        {
            givesugar ();
            Givebiscuit ();
            Givelolipop ();
        }
        private static void GiveChildren2 ()
        {
            givesugar ();
            Givecake ();
            Givebiscuit ();
        }
        private static void GiveChildren3 ()
        {
            givelolipop ();
            Givesugar ();
            Givecake ();
        }

and using enum and switch statements

public enum children{
Jojo,meme,kiki
}

private static void Givechildren (Children Children)
{
 Switch (children)
            {case
                Children.jojo:
                    GiveChildren1 ();
                    break;
                Case Children.meme:
                    GiveChildren2 ();
                    break;
                        Case Children.kiki:
                    GiveChildren3 ();
                    break;
                Default:
                    Givesugar ();
                    break;
            }
}

While this can solve the need, scalability is very poor, we want to add a new set of incentives to add new methods and modify the enumeration type and switch statements.

If we use delegates, we can solve this problem:

Because you can dynamically decide which method to use, we do not need to enumerate here.

Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Text;

Using System.Threading.Tasks;

        Namespace DelegateTest {Class Program {public delegate void Rewarddelegate ();
            static void Main (string[] args) {rewarddelegate rewardall,reward1, reward2, Reward3;
            Rewardall = Givesugar;
            Rewardall + = Givebiscuit;
            Rewardall + = Givecake;
            Rewardall + = Givelolipop;
            Reward1 = Rewardall-givecake;
            Reward2 = Rewardall-givelolipop;
            Reward3 = Rewardall-givebiscuit;
            Givechildren ("Jojo", Reward2);
        Console.readkey ();
        The private static void Givelolipop () {//Gives Lollipop Console.WriteLine ("Lollipop");
        The private static void Givecake () {//gave the cake Console.WriteLine ("To the Cake");
         private static void Givesugar () {   Gave the Candy Console.WriteLine ("Give Candy");
        The private static void Givebiscuit () {//gave the cookie Console.WriteLine ("to the Cookie");
            private static void Givechildren (String Name,rewarddelegate Rd) {if (rd!= null)
                {Console.WriteLine ("Give" + name + "reward has:");
            Rd.invoke (); }
        }
    }
}

Run the results as shown in figure:


This example may not be very good, but we can dynamically decide which method to use, the code is a lot simpler, so that the program's extensibility more flexible.

So delegates allow us to avoid a lot of use of conditional statements (If,switch), while avoiding duplication of code.

If there are other students who do not understand, I will give a simple example.

Suppose you need to decorate the house, you need to give the decoration workers a decoration plan, then the code can write:

public delegate void Decoratedelegate ();
        static void Main (string[] args)
        {
            decoratehouse (classicstyle);
            Console.readkey ();
        }
        private void Classicstyle ()
        {
            Console.WriteLine ("You chose the classic Decoration scheme");
        }
        private void Decoratehouse (decoratedelegate dd)
        {
            if (dd!= null)
                DD. Invoke ();
        }

When you need to change the decoration scheme, you only need to change the parameters in the Decoratehouse, it is much simpler to operate.

Second, when you need to implement the communication between two classes

Let's look at the last example:

Namespace DelegateTest2
{
    class program
    {
        static void Main (string[] args)
        {
            Myclass Myclass = New Myclass ();
            Myclass.working ();
        }
    Class Myclass
    {public
        void Working ()
        {for
            (int i=0;i<10000;i++)
            {
                //handling event
            }
        }
    }
}


In such an example, if the program class wants to get the information in the MyClass working method in real time while it is running, we can use the delegate to implement it.

Class program
    {
       
        static void Main (string[] args)
        {
            Myclass Myclass = new Myclass ();
            Myclass.working (CallBack);
        }
        private static void CallBack (int i)
        {
            Console.WriteLine (i);
        }
    }
    Class Myclass
    {public
        delegate void CallBack (int i);
        public void Working (CallBack CallBack)
        {for
            (int i=0;i<10000;i++)
            {
                //handling event
                CallBack (i) ;
            }
        }
}

We pass the callback method in the program class to the working method, which gets the callback.

Simply put, MyClass uses the callback method in program to output information.

Don't ask me why I don't direct public static and then call directly, we consider the encapsulation of the object.

The results of the program operation are shown as follows:

Summary: In addition to passing the method as a parameter, the main function of the delegate is to implement the communication between the two parties and then implement the callback.

 

an in-depth understanding of the mandate

==================================================================

1. covariance and contravariance of Delegates

Before the Framework 2.0, there was no notion of a covariant concept.

As an example:

public class Human

{.......}

public class Man:human

{.......}

Public delegate Human Humanhandler (int id);

Public delegate mans Manhandler (int id);

Here Humanhandler are unable to bind the return value to man because they are treated as two different types, although the mans inherits to human.

And after the Framework 2.0 version, there is the concept of the principal covariant

We can directly bind a method that returns a value of man:

Humanhandler hh=new Humanhandler (Manhandler);

Man man=hh as Mans;

The only difference between the delegate inversion and the delegate covariance is that it uses object as the delegate of the argument, and then the is to judge the type of object.

Class program
    {public
        delegate void Handler (object obj);

        public static void GetMessage (Object message)
        {
            if (message is String)
                Console.WriteLine ("He name is:" + Me Ssage. ToString ());
            If (the message was int)
                Console.WriteLine ("His Age is:" + message.) ToString ());
        }

        static void Main (string[] args)
        {
            Handler Handler = new Handler (GetMessage);
            Handler (a);
            Console.readkey ();
        }
   

2. Generic Delegate

For the above method, if all with object as a parameter, every time the unboxing operation is very consuming performance, the process is very cumbersome.

Therefore, the concept of generic delegates is introduced here.

  Class program
    {public
        delegate void handler<t> (T obj);
        static void Main (string[] args)
        {
            handler<int> handler1 = new handler<int> (getsquare);
            handler<string> handler2 = new handler<string> (sayhi);
            Handler1 (2);
            Handler2 ("Wix");
            Console.readkey ();
        }
        static void Getsquare (int a)
        {
            Console.WriteLine (A * a);
        }
        static void Sayhi (string name)
        {
            
            Console.WriteLine ("Hi," +name);
        }
}

Output as shown in figure:

when to use a generic delegate.

If you want to bind multiple different types of parameter methods, you can use generic delegates, and you do not need to use is for type judgment. So that we don't have to define multiple delegates with different parameter types.

what is an event.

In simple terms, the origin of the event is to ensure the encapsulation of the system.

The above code can see that the declaration of the delegate is public, which allows the outside world to invoke or assign operations directly.

If set to private, we need to add AddHandler and RemoveHandler methods (+ = and =), just like get and set methods, very cumbersome.

So the concept of the event was born.

public class Eventtest
  {public
      delegate void MyDelegate ();
      public event MyDelegate myevent;
   }
 


* the variable member corresponding to the event will be treated as a private variable

If you do not understand, you can imagine that the event is entrusted to the container, can guarantee the encapsulation of the delegate.

Events can be registered or unregistered by + = and-= Two ways to deal with them


public delegate void MyDelegate (string name);

    public class Personmanager
    {public
        event MyDelegate MyEvent;

        Execute event public
        void execute (string name)
        {
            if (myevent!= null)
                MyEvent (name);
        }

    Class program
    {
        static void Main (string[] args)
        {
            Personmanager personmanager = new Personmanager ( );
            Binding event Handling Method
            Personmanager.myevent + = new MyDelegate (GetName);
            Personmanager.execute ("Leslie");
            Console.readkey ();
        }

        public static void GetName (string name)
        {
            Console.WriteLine (' My name is ' + name);
        }
    }

We can also directly bind the method

Personmanager.myevent + = GetName;

Or bind anonymous methods

Personmanager.myevent + = delegate (string name) {

Console.WriteLine ("My Name is" +name);

};

Summary: The event is a special delegate.

when to use the event.

Events can split a logical process into stages, in a game, such as when a unit produces something that triggers an event, and an event is triggered when the unit dies.

Here is the code example in the simulation unity:

 Class Unithandler {public delegate void Uniteventhandler (Gameobject);
        public static event Uniteventhandler Onunitspawn;
        public static event Uniteventhandler Onunitdestroy; public static void newunitcreated (Gameobject unit) {if (onunitspawn!= null) ONUNITSP
        Awn (unit); public static void Unitdead (Gameobject unit) {if (onunitdestroy!=null) onunitdes
       
        Troy (unit); The class Unitmanager {public void onenabled () {unithandler.onunitspawn + = this.
        newunitcreated;
            public void newunitcreated (Gameobject unit) {Console.WriteLine ("Unit created");
        Console.readkey (); public void Ondisable () {unithandler.onunitspawn = this.
        newunitcreated; } class Program {static void Main (string[] args) {UNitmanager um = new Unitmanager (); Um.
            Onenabled ();
            unithandler.newunitcreated (New Gameobject ()); Um.
            Ondisable ();
        unithandler.newunitcreated (New Gameobject ()); }
    }

* The gameobject here is an empty class

The results of the operation are:

Unit created


An event can have an object notify another object when an event occurs, which can be understood to listen for an event and then trigger under certain conditions.

Let's look at one more example:

Before we create an event, we need a delegate, and the general standard delegate declaration is as follows:

public delegate void EventHandler (object sender, System.EventArgs e);

The first Parameter object sender defines the source of the object, and the second parameter is a class that inherits from System.EventArgs, which generally contains the details of the event.

Example:

Class Buttoneventargs:eventargs

{

public string time;

}

Here we do not need to pass any event information, so we use the base class EventArgs.

public delegate void EventHandler (object sender, System.EventArgs e);

    Class Publisher
    {public
        event EventHandler Added;//define occurrence


        protected virtual void onadded ( System.EventArgs e)///When the event occurs the triggering method
        {
            if (added!=null)
            {
                Added (this, e);
            }
        }
        The public void Add (object value)//Trigger event method
        {
   
            onadded (System.EventArgs.Empty);
        }



    Class subscriber
    {
        void Addedeventhandler (Object Sender,system.eventargs e)
        {
            System.Console.WriteLine ("addevent occured");
        }
        
        static void Main ()
        {
            subscriber s = new Subscriber ();
            Publisher P = new publisher ();
            p.added + = S.addedeventhandler;
P.add (ten);
        }
}


The following steps are used for the event:

class that holds events

1. Defining events

2. Method of triggering event (protected)

3. Methods of indirect triggering of events (public)

class that triggers the event

1. Definition method

2. Registration method

3. Trigger method

Let's look at the last example:

public class Myeventargs:eventargs {private string args;
        Public MyEventArgs (String message) {args = message;
            public string: {get {args;}
        set {args = value;}

        } public class EventManager {public event eventhandler<myeventargs> MyEvent; public void Execute (String message) {if (myevent!= null) MyEvent (this, new Myeventar
        GS (message));  } class Program {static void Main (string[] args) {EventManager EventManager =
            New EventManager ();
            Eventmanager.myevent + = new eventhandler<myeventargs> (showmessage);
            Eventmanager.execute ("How are you!");
        Console.readkey ();
        public static void ShowMessage (Object Obj,myeventargs e) {Console.WriteLine (e.message); }
    }

Here we use the eventhandler<teventargs> to construct the required delegates.

public delegate void Eventhandler<teventargs> (Object sender, Teventargs e)

MyEventArgs is responsible for storing event information.

EventManager is responsible for the definition and execution of events.

The program is responsible for defining the triggers for methods and events.

Summarize:

A delegate is a class that derives from System.multcastdelegate, and the event is a special delegate that is used synchronously with the delegate type.

Part of this article refers to this article and adds a personal understanding:

Http://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.