search
HomeBackend DevelopmentC#.Net TutorialC# delegate, introduction to event understanding

Table of contents

l Introduction

l What is delegation

l Understanding of events

l Event keywords

l Finally



Introduction

In the process of learning delegates and events in C#, I read a lot Article to understand what they are and how to use them. Now I will describe the entire understanding process below. Every aspect I learned is probably what you need to master:-).

What is delegation?

The two concepts of delegation and events are completely compatible. A delegate is just a function pointer, that is, it can refer to a function, through the mechanism of passing the address. A delegate is a class that, when you instantiate it, provides a reference function as a parameter to its constructor.

Each delegate has its own signature, for example: Delegate int SomeDelegate(string s, bool b); is a delegate declaration. The signature mentioned here means that the delegate SomeDelegate has formal parameters of string and bool types. , returns an int type.

Mentioned above: When you instantiate a delegate, provide a reference function as a parameter to its constructor. Note here: the function being referenced must have the same signature as the delegate.

Look at the following function:

PRivate int SomeFunction(string str, bool bln){...}

You can pass this function to the constructor of SomeDelegate since they have similar signatures (in other Words, they All have the same parameter type and number, and return the same data type).

SomeDelegate sd = new SomeDelegate(SomeFunction);

sd refers to SomeFunction, that is to say, SomeFunction has been registered by sd. If you call sd, the function SomeFunction will also be called. Remember: I said SomeFunction The meaning of , we will use it later.

Now, you should know how to use delegates, let us continue to understand the event journey...

Understanding of events

We know that in C#:

l Button is a class, when we click When it does, a click event is triggered.

l The clock (Timer) is also a class. Every millisecond, a tick event is triggered.


Let us learn through an example, assuming there is such a plot:

Now there is a Counter class, which has a method CountTo(int countTo, int reachableNum), which means: within the specified time period ( 0~~countTo), when the specified time point reachableNum is reached, a NumberReached event is triggered.

It also has an event: NumberReached, which is a delegate type variable. Meaning: If you name an event, declare it with the event keyword and the delegate type to be used, as shown below:

public event NumberReachedEventHandler NumberReached;



In the above declaration, NumberReachedEventHandle is just a delegate. A more accurate representation should be: NumberReachedDelegate. But Microsoft never thinks of MouseDelegate or PaintDelegate this way, but the title: MouseEventHandler or PaintEventHandler. So

NumberReachedEventHandler sounds more convenient than NumberReachedDelegate, OK? Okay, let's continue, now you know, before we declare the event, we need to define the delegate in the following form:

public delegate void NumberReachedEventHandler(object sender, NumberReachedEventArgs e);

Now declare the delegate NumberReachedEventHandle, which has a void return value and two formal parameters of object and NumberReachedEventArgs. As we emphasized in Section 1, when instantiating a delegate, the function passed as an argument must also have the same signature as the delegate.

In your code, have you used PaintEventArgs or MouseEventArgs to determine the movement position of the mouse? Have you used the Graphics property on the object that triggered the Paint event? In fact, the classes that provide data for users all inherit from the System.EventArgs class, which is what we often call the event parameter class. If the event does not provide parameters, this class will not be defined. In our case, we provide the expected time point through the following class.

public class NumberReachedEventArgs : EventArgs

{

private int _reached;

public NumberReachedEventArgs(int num)

{

this._reached = num;

}

public int ReachedNumber

{

get

return _reached;

                                                                                                                                Take a look inside the Counter class:

namespace Events

{

  public delegate void NumberReachedEventHandler(object sender,

                                               .

​ /// Summary description for Counter. " public Counter()​​​​

//

} u Public Void Countto (Int Countto, Int Reachablenum) {

IF (Counto & LT; Reachablenum)

Throw New ArgumentedException (

Reachab Lenum should be less than countto ");
               for (int ctr=0;ctr
                       NumberReachedEventArgs                                                       e); Return; //d'T to Count Any More

}}}}









)

{{{ NumberReached(this, e);//Raise the event

}

}

}

}

In Counter, if the specified time point is reached, an event is triggered. There are the following aspects to pay attention to:

l Complete a trigger event by calling NumberReached (which is an instance of the NumberReachedEventHandler delegate).

NumberReached(this, e); In this way, all registered functions can be called.

l Provide event data for all registered functions through NumberReachedEventArgs e = new NumberReachedEventArgs(reachableNum);

l After reading the above code, you may want to ask: Why do we directly use the OnNumberReached(NumberReachedEventArgs e) method to call NumberReached(this, e) instead of the following code?

if(ctr == reachableNum)

{

NumberReachedEventArgs e = new NumberReachedEventArgs(reachableNum);

//OnNumberReached(e);

if(NumberReached != null )

                                                                         e);//Raise the event

}

return;//don't count any more

}

This is a good question, so let us take another look at the OnNumberReached signature:

protected virtual void OnNumberReached(NumberReachedEventArgs e)

① You also understand that the keyword protected restricts that only classes that inherit from this class can call all methods in this class.

②The keyword virtual indicates that this method can be overridden in inherited classes.

These two points are very useful. Suppose you are writing a class that inherits from Counter. By overriding the OnNumberReached method, you can perform other work before the event is triggered.



protected override void OnNumberReached(NumberReachedEventArgs e)

{

  //Do additional work

base.OnNumberReached(e);

}

Note: If you do not call base.On NumberReached(e), then This event is never triggered! This is useful when you inherit from a class and want to exclude some of its other events.

l It should also be noted that the delegate NumberReachedEventHandler is defined outside the class definition, within the namespace, and is visible to all classes.

Okay, it’s time for us to actually use the Counter class.



In our simple application, we have two text boxes, namely: txtCountTo and txtReachable:




The following is the click event of btnRun:

private void btnRun_Click(object sender, System.EventArgs e)

                                                                                                                                                    vert.ToInt32(txtCountTo.Text), Convert.ToInt32(txtReachable .Text)); eachedNumber.ToString());

}



The syntax for initializing event handling is as follows:

oCounter = new Counter();

              oCounter.NumberReached += new NumberReachedEventHandler(oCounter_NumberReached); , only initialize the NumberReachedEventHandler delegate type object (just like you instantiate other objects), notice that the signature of the oCounter_NumberReached method is similar to what I mentioned earlier.

Also note that we use += instead of =; this is because a delegate is a special object that can refer to multiple objects (here it means that it can refer to multiple functions). For example if there is another function oCounter_NumberReached2 with the same signature as oCounter_NumberReached, both functions can be referenced:



oCounter = new Counter();

oCounter.NumberReached += new NumberReachedEventHandler(oCounter _NumberReached) ;

oCounter.NumberReached += new NumberReachedEventHandler(oCounter_NumberReached2);

Now, after an event is triggered, the above two functions are called in sequence.



Depending on the situation, if you want oCounter_NumberReached2 to no longer be called after the NumberReached event occurs, you can simply write like this: oCounter.NumberReached -= new NumberReachedEventHandler(oCounter_NumberReached2);



Finally Let’s take a look Complete source code for reference:


Form1.cs


using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System .Data;

namespace Events
{
  /**////

 
    /// Summary description for Form1. 
    ///
 
    public class Form1 : System.Windows.Forms.Form 
    { 
        Counter oCounter = null; 

        private System.Windows.Forms.Button cmdRun; 
        private System.Windows.Forms.TextBox txtReachable; 
        private System.Windows.Forms.TextBox txtCountTo; 
        private System.Windows.Forms.Label label1; 
        private System.Windows.Forms.Label label2; 
        private System.Windows.Forms.Button btnRemoveDelegate; 
        /**////
                /// Required designer variable. container components = null;

public Form1()
izeComponent();​​​​​​​​​
                        oCounter = new Counter();                                                             use using using using ‐ ‐ oCounter.NumberReached += new ‐NumberReachedEventHandler(oCounter_NumberReached); 2); / Clean up any resources being used.
                                                                                                                                                                                                                                                                               through );        } 

        Windows Form Designer generated code#region Windows Form Designer generated code 
        /**////  
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor. 
        ///
 
        private void InitializeComponent() 
        { 
            this.cmdRun = new System.Windows.Forms.Button(); 
            this.txtReachable = new System.Windows.Forms.TextBox(); 
            this.txtCountTo = new System.Windows.Forms.TextBox(); 
            this.label1 = new System.Windows.Forms.Label(); 
            this.label2 = new System.Windows.Forms.Label(); 
            this.btnRemoveDelegate = new System.Windows.Forms.Button(); 
            this.SuspendLayout(); 
            //  
            // cmdRun 
            //  
            this.cmdRun.Location = new System.Drawing.Point(16, 72); 
            this.cmdRun.Name = "cmdRun"; 
            this.cmdRun.Size = new System.Drawing.Size(48, 23); 
            this.cmdRun.TabIndex = 2; 
            this.cmdRun.Text = "Run"; 
            this.cmdRun.Click += new System.EventHandler(this.cmdRun_Click); 
            //  
            // txtReachable 
            //  
            this.txtReachable.Location = new System.Drawing.Point(144, 40); 
            this.txtReachable.Name = "txtReachable"; 
            this.txtReachable.Size = new System.Drawing.Size(56, 20); 
            this.txtReachable.TabIndex = 1; 
            this.txtReachable.Text = ""; 
            //  
            // txtCountTo 
            //  
            this.txtCountTo.Location = new System.Drawing.Point(144, 16); 
            this.txtCountTo.Name = "txtCountTo"; 
            this.txtCountTo.Size = new System.Drawing.Size(56, 20); 
            this.txtCountTo.TabIndex = 0; 
            this.txtCountTo.Text = ""; 
            //  
            // label1 
            //  
            this.label1.AutoSize = true; 
            this.label1.Location = new System.Drawing.Point(16, 16); 
            this.label1.Name = "label1"; 
            this.label1.Size = new System.Drawing.Size(51, 13); 
            this.label1.TabIndex = 3; 
            this.label1.Text = "Count To"; 
            //  
            // label2 
            //  
            this.label2.AutoSize = true; 
            this.label2.Location = new System.Drawing.Point(16, 40); 
            this.label2.Name = "label2"; 
            this.label2.Size = new System.Drawing.Size(99, 13); 
            this.label2.TabIndex = 4; 
            this.label2.Text = "Reach this number"; 
            //  
            // btnRemoveDelegate 
            //  
            this.btnRemoveDelegate.Location = new System.Drawing.Point(16, 104); 
            this.btnRemoveDelegate.Name = "btnRemoveDelegate"; 
            this.btnRemoveDelegate.Size = new System.Drawing.Size(168, 23); 
            this.btnRemoveDelegate.TabIndex = 5; 
            this.btnRemoveDelegate.Text = "Remove second handler"; 
            this.btnRemoveDelegate.Click += new System.EventHandler(this.btnRemoveDelegate_Click); 
            //  
            // Form1 
            //  
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); 
            this.ClientSize = new System.Drawing.Size(224, 134); 
            this.Controls.AddRange(new System.Windows.Forms.Control[] { 
                                                                          this.btnRemoveDelegate, 
                                                                          this.label2, 
                                                                          this.label1, 
                                                                          this.txtCountTo, 
                                                                          this.txtReachable, 
                                                                          this.cmdRun}); 
            this.Name = "Form1"; 
            this.Text = "Events"; 
            this.ResumeLayout(false); 

        } 
        #endregion 

        /**////  
        /// The main entry point for the application. 
        ///
 
        [STAThread] 
        static void Main()  
        { 
            Application.Run(new Form1()); 
        } 

        private void btnRun_Click(object sender, System.EventArgs e) 
        { 
            if(txtCountTo.Text == "" || txtReachable.Text=="") 
                return; 
            oCounter.CountTo(Convert.ToInt32(txtCountTo.Text), Convert.ToInt32(txtReachable.Text)); 
        } 

        private void oCounter_NumberReached(object sender, NumberReachedEventArgs e) 
        { 
            MessageBox.Show("Reached: " + e.ReachedNumber.ToString()); 
        } 
        private void oCounter_NumberReached2(object sender, NumberReachedEventArgs e) 
        { 
            MessageBox.Show("Reached2: " + e.ReachedNumber.ToString()); 
        } 

        private void btnRemoveDelegate_Click(object sender, System.EventArgs e) 
        { 
            oCounter.NumberReached -= new NumberReachedEventHandler(oCounter_NumberReached2); 
            oCounter.CountTo(Convert.ToInt32(txtCountTo.Text), Convert.ToInt32(txtReachable.Text)); 
        } 
    } 

  






Counter.cs 


  

using System; 

namespace Events 

    public delegate void NumberReachedEventHandler(object sender, NumberReachedEventArgs e); 

    /**////  
    /// Summary description for Counter. 
    ///
 
    public class Counter 
    { 
        public event NumberReachedEventHandler NumberReached; 
         
        public Counter() 
        { 
            // 
            // TODO: Add constructor logic here 
            // 
        } 
        public void CountTo(int countTo, int reachableNum) 
        { 
            if(countTo                 throw new ArgumentException("reachableNum should be less than countTo"); 
            for(int ctr=0;ctr            { 
                if(ctr == reachableNum) 
                { 
                    NumberReachedEventArgs e = new NumberReachedEventArgs(reachableNum); 
                    OnNumberReached(e); 
                    return;//don't count any more 
                } 
            } 
        } 

        protected virtual void OnNumberReached(NumberReachedEventArgs e) 
        { 
            if(NumberReached!=null) 
            { 
                NumberReached(this, e); 
            } 
        } 
    } 

    public class NumberReachedEventArgs : EventArgs 
    { 
        private int _reached; 
        public NumberReachedEventArgs(int num) 
        { 
            this._reached = num; 
        } 
        public int ReachedNumber 
        { 
            get 
            { 
                return _reached; 
            } 
        } 
    } 

 以上就是C#委托,事件理解入门的内容,更多相关内容请关注PHP中文网(www.php.cn)! 


Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
C# .NET and the Future: Adapting to New TechnologiesC# .NET and the Future: Adapting to New TechnologiesApr 14, 2025 am 12:06 AM

C# and .NET adapt to the needs of emerging technologies through continuous updates and optimizations. 1) C# 9.0 and .NET5 introduce record type and performance optimization. 2) .NETCore enhances cloud native and containerized support. 3) ASP.NETCore integrates with modern web technologies. 4) ML.NET supports machine learning and artificial intelligence. 5) Asynchronous programming and best practices improve performance.

Is C# .NET Right for You? Evaluating its ApplicabilityIs C# .NET Right for You? Evaluating its ApplicabilityApr 13, 2025 am 12:03 AM

C#.NETissuitableforenterprise-levelapplicationswithintheMicrosoftecosystemduetoitsstrongtyping,richlibraries,androbustperformance.However,itmaynotbeidealforcross-platformdevelopmentorwhenrawspeediscritical,wherelanguageslikeRustorGomightbepreferable.

C# Code within .NET: Exploring the Programming ProcessC# Code within .NET: Exploring the Programming ProcessApr 12, 2025 am 12:02 AM

The programming process of C# in .NET includes the following steps: 1) writing C# code, 2) compiling into an intermediate language (IL), and 3) executing by the .NET runtime (CLR). The advantages of C# in .NET are its modern syntax, powerful type system and tight integration with the .NET framework, suitable for various development scenarios from desktop applications to web services.

C# .NET: Exploring Core Concepts and Programming FundamentalsC# .NET: Exploring Core Concepts and Programming FundamentalsApr 10, 2025 am 09:32 AM

C# is a modern, object-oriented programming language developed by Microsoft and as part of the .NET framework. 1.C# supports object-oriented programming (OOP), including encapsulation, inheritance and polymorphism. 2. Asynchronous programming in C# is implemented through async and await keywords to improve application responsiveness. 3. Use LINQ to process data collections concisely. 4. Common errors include null reference exceptions and index out-of-range exceptions. Debugging skills include using a debugger and exception handling. 5. Performance optimization includes using StringBuilder and avoiding unnecessary packing and unboxing.

Testing C# .NET Applications: Unit, Integration, and End-to-End TestingTesting C# .NET Applications: Unit, Integration, and End-to-End TestingApr 09, 2025 am 12:04 AM

Testing strategies for C#.NET applications include unit testing, integration testing, and end-to-end testing. 1. Unit testing ensures that the minimum unit of the code works independently, using the MSTest, NUnit or xUnit framework. 2. Integrated tests verify the functions of multiple units combined, commonly used simulated data and external services. 3. End-to-end testing simulates the user's complete operation process, and Selenium is usually used for automated testing.

Advanced C# .NET Tutorial: Ace Your Next Senior Developer InterviewAdvanced C# .NET Tutorial: Ace Your Next Senior Developer InterviewApr 08, 2025 am 12:06 AM

Interview with C# senior developer requires mastering core knowledge such as asynchronous programming, LINQ, and internal working principles of .NET frameworks. 1. Asynchronous programming simplifies operations through async and await to improve application responsiveness. 2.LINQ operates data in SQL style and pay attention to performance. 3. The CLR of the NET framework manages memory, and garbage collection needs to be used with caution.

C# .NET Interview Questions & Answers: Level Up Your ExpertiseC# .NET Interview Questions & Answers: Level Up Your ExpertiseApr 07, 2025 am 12:01 AM

C#.NET interview questions and answers include basic knowledge, core concepts, and advanced usage. 1) Basic knowledge: C# is an object-oriented language developed by Microsoft and is mainly used in the .NET framework. 2) Core concepts: Delegation and events allow dynamic binding methods, and LINQ provides powerful query functions. 3) Advanced usage: Asynchronous programming improves responsiveness, and expression trees are used for dynamic code construction.

Building Microservices with C# .NET: A Practical Guide for ArchitectsBuilding Microservices with C# .NET: A Practical Guide for ArchitectsApr 06, 2025 am 12:08 AM

C#.NET is a popular choice for building microservices because of its strong ecosystem and rich support. 1) Create RESTfulAPI using ASP.NETCore to process order creation and query. 2) Use gRPC to achieve efficient communication between microservices, define and implement order services. 3) Simplify deployment and management through Docker containerized microservices.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),