C # Event Learning diary,

Source: Internet
Author: User

C # Event Learning diary,

The reason for the event keyword is to simplify the construction of custom methods to add and delete methods for the delegated call list.

When the compiler processes the event keyword, it automatically provides the registration and logout methods and any necessary delegate type member variables.

These delegate member variables are always declared private, so they cannot be accessed directly from the trigger event object.

 

Tip: if you are not familiar with delegation, you can check the C # delegation first. This will help you understand this chapter.

Procedure for defining an event:

Let's look at an example:

 

1. Define the Car class:

Public class Car {// This delegate is used to collaborate with Car events public delegate void CarEngineHandler (string msg );

// This type of car can send these events public event CarEngineHandler Exploded; public event CarEngineHandler AboutToBlow; public int CurrentSpeed {get; set;} public int MaxSpeed {get; set ;} public string PetName {get; set;} private bool CarIsDead; public Car () {MaxSpeed = 100;} public Car (string name, int maxSp, int currSp) {CurrentSpeed = currSp; maxSpeed = maxSp; PetName = name;} public void Accelerate (int de Lta) {// if the Car cannot be used, the Exploded event if (CarIsDead) {if (Exploded! = Null) {Exploded ("sorry, this car is dead") ;}} else {CurrentSpeed + = delta; // confirm that it is unavailable, trigger the AboutToBlow event if (MaxSpeed-CurrentSpeed) = 10 & AboutToBlow! = Null) {AboutToBlow ("careful buddy! Gonna blow! ") ;}If (CurrentSpeed >=maxspeed) {CarIsDead = true ;}else {Console. WriteLine ($" CurrentSpeed = {CurrentSpeed }");}}}}

We have set the Car object to send two custom events, which no longer requires a user-defined registration function or a delegate member variable. We will talk about how to use this car later. Before that, let's take a look at the event architecture and unveil the mysteries of the event.

 

2. Event mystery

C # events actually expand two hidden public methods, one add _ event name and one remove _ event name.

 

Add_Exploded () Pencil command

 

Remove_Exploded () Pencil command

 

It indicates that the server code of the event uses the. addon and. removeon commands to call the corresponding add_xxx () and remove_xxx () methods.

 

3. Use the Car class

After learning about this, we will use the previously defined Car class:

Public class MyEvent {public static void Show () {WriteLine ("fun with events"); Car c1 = new Car ("bwm", 100, 10 ); // register the event handler c1.AboutToBlow + = new Car. carEngineHandler (CarIsAlomostDoomed); c1.AboutToBlow + = new Car. carEngineHandler (CarAboutToBlow); Car. carEngineHandler d = new Car. carEngineHandler (CarExploded); c1.Exploded + = d; WriteLine ("****** Speeding up ******"); for (int I = 0; I <6; I ++) {c1.Accelerate (20) ;}// deregister, remove the CarExploded () method c1.Exploded-= d from the call list; writeLine ("******* Speeding up ******"); for (int I = 0; I <6; I ++) {c1.Accelerate (20) ;}} private static void CarExploded (string msg) => WriteLine ($ "CarExploded-> {msg}"); private static void CarAboutToBlow (string msg) => WriteLine ($ "CarAboutToBlow => {msg}"); private static void CarIsAlomostDoomed (string msg) => WriteLine ($ "CarIsAlomostDoomed-> {msg }");}

 

Run:

 

To further simplify event registration, we can use the method group conversion syntax learned in the delegate chapter (explanation: I can directly provide the method name when calling a method with the delegate as a parameter, instead of the delegate object)

The following describes how to use group conversion, registration, and logout events,BoldPart:

Public static void Show () {WriteLine ("fun with events"); Car c1 = new Car ("bwm", 100, 10); // register the event handlerC1.AboutToBlow + = CarIsAlomostDoomed; c1.AboutToBlow + = CarAboutToBlow; c1.Exploded + =CarExploded;WriteLine ("******* Speeding up ******"); for (int I = 0; I <6; I ++) {c1.Accelerate (20 );}
// Log out and remove the CarExploded () method from the call list.C1.Exploded-=CarExploded;WriteLine ("******* Speeding up ******"); for (int I = 0; I <6; I ++) {c1.Accelerate (20 );}}

 

4. Create Custom Event Parameters

Microsoft Event Mode: (System. Object sender, System. EventArgs args.

The first parameter sender indicates a reference to the object (Car) that sends the event,

The second parameter args: information related to the event

System. EventArgs base class source code:

public class EventArgs {    public static readonly EventArgs Empty = new EventArgs();        public EventArgs()     {    }}

For simple event types, we can directly pass an EventArgs instance, but if we want to pass custom data, we should derive a subclass from System. EventArgs.
Next, we will create a CarEventArgs class for our Car to customize an event parameter that complies with this event mode. It contains a string to indicate the information to be sent to the receiver:

public class CarEventArgs : EventArgs{    public readonly string msg;    public CarEventArgs(string message)    {        msg = message;    }}

 

Modify the Car class, add a new CarCustomEngineHandler delegate, and change the corresponding Event code:

Public class Car {public delegate void CarCustomEngineHandler; public void AccelerateCustom (int delta) {if (CarIsDead) {if (mexmexploded! = Null) {CustomExploded (this, new CarEventArgs ("sorry, this car is dead") ;}} else {CurrentSpeed + = delta; if (MaxSpeed-CurrentSpeed) = 10 & CustomAboutToBlow! = Null) {CustomAboutToBlow (this, new CarEventArgs ("careful buddy! Gonna blow! ");} If (CurrentSpeed> = MaxSpeed) {CarIsDead = true;} else {Console. WriteLine ($" CurrentSpeed = {CurrentSpeed }");}}}}

 

Let's take a look at the callBoldPart (how to use the passed parameter sender, e ):

public class MyCustomEvents{    public static void Show()    {        WriteLine("fun with events");        Car c1 = new Car("bwm", 100, 10);        c1.CustomAboutToBlow += CarIsAlomostDoomed;        c1.CustomAboutToBlow += CarAboutToBlow;        Car.CarCustomEngineHandler d = CarExploded;        c1.CustomExploded += d;        WriteLine("******Speeding up******");        for (int i = 0; i < 6; i++)        {            c1.AccelerateCustom(20);        }        c1.CustomExploded -= d;        WriteLine("******Speeding up******");        for (int i = 0; i < 6; i++)        {            c1.AccelerateCustom(20);        }    }    private static void CarExploded(object sender, CarEventArgs e) => WriteLine($"CarExploded->{((Car)sender)?.PetName} {e.msg}");    private static void CarAboutToBlow(object sender, CarEventArgs e) => WriteLine($"CarAboutToBlow=>{((Car)sender)?.PetName} {e.msg}");    private static void CarIsAlomostDoomed(object sender, CarEventArgs e) => WriteLine($"CarIsAlomostDoomed->{((Car)sender)?.PetName} {e.msg}");}


5. Generic EventHandler <T> delegate

Public delegate void EventHandler <TEventArgs> (object sender, TEventArgs e );

Because many custom delegate acceptance (object, EventArgs) parameter structures, we can use the built-in EventHandler framework <> to simplify our event delegation.

 

First, modify the Car class:

public class Car{    public event EventHandler<CarEventArgs> StandardExploded;    public event EventHandler<CarEventArgs> StandardAboutToBlow;    public void AccelerateStandard(int delta)    {        if (CarIsDead)        {            if (StandardExploded != null)            {                StandardExploded(this, new CarEventArgs("sorry,this car is dead"));            }        }        else        {            CurrentSpeed += delta;            if ((MaxSpeed - CurrentSpeed) == 10 && StandardAboutToBlow != null)            {                StandardAboutToBlow(this, new CarEventArgs("careful buddy ! gonna blow !"));            }            if (CurrentSpeed >= MaxSpeed)            {                CarIsDead = true;            }            else            {                Console.WriteLine($"CurrentSpeed={CurrentSpeed}");            }        }    }}


The calling code is actually not much different from the previous one. I will post it here:

public class MyStandardEvent{    public static void Show()    {        WriteLine("fun with events");        Car c1 = new Car("bwm", 100, 10);        c1.StandardAboutToBlow += CarIsAlomostDoomed;        c1.StandardAboutToBlow += CarAboutToBlow;        EventHandler<CarEventArgs> d = CarExploded;        c1.StandardExploded += d;        WriteLine("******Speeding up******");        for (int i = 0; i < 6; i++)        {            c1.AccelerateStandard(20);        }        c1.StandardExploded -= d;        WriteLine("******Speeding up******");        for (int i = 0; i < 6; i++)        {            c1.AccelerateStandard(20);        }    }    private static void CarExploded(object sender, CarEventArgs e) => WriteLine($"CarExploded->{((Car)sender)?.PetName} {e.msg}");    private static void CarAboutToBlow(object sender, CarEventArgs e) => WriteLine($"CarAboutToBlow=>{((Car)sender)?.PetName} {e.msg}");    private static void CarIsAlomostDoomed(object sender, CarEventArgs e) => WriteLine($"CarIsAlomostDoomed->{((Car)sender)?.PetName} {e.msg}");}

 

 

6. Anonymous Method

For such a simple processing operation, the CarExploded (), CarAboutToBlow () method is rarely called by any program other than the call delegate. In terms of generation efficiency, it is a bit difficult to manually define a method called by the delegate object.

To solve this problem, you can directly associate a delegate with a piece of code when registering an event --Anonymous Method.

Let's modify the location where the Car class is called (note:BoldSection and the last braces";"End ):

public class MyAnonymousMtehoden{    public static void Show()    {        int aboutToBlowCounter = 0;        WriteLine("fun with events");        Car c1 = new Car("bwm", 100, 10);        c1.StandardAboutToBlow += delegate        {            WriteLine("Eek,going to fast");        };        c1.StandardAboutToBlow += delegate (object sender, CarEventArgs e)        {            aboutToBlowCounter++;            WriteLine($"CarAboutToBlow=>{((Car)sender)?.PetName} {e.msg}");        };        c1.StandardExploded += delegate (object sender, CarEventArgs e)        {            aboutToBlowCounter++;            WriteLine($"Exploded=>{((Car)sender)?.PetName} {e.msg}");        };        for (int i = 0; i < 6; i++)        {            c1.AccelerateStandard(20);        }        WriteLine($"aboutToBlowCounter={aboutToBlowCounter}");    }}

 

This article references proficient C #

 

There is no end to learning. I hope you can give me more advice.

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.