C sharp #006# 委托与事件

Posted xkxf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C sharp #006# 委托与事件相关的知识,希望对你有一定的参考价值。

饮水思源:金老师的自学网站

委托(Delegate)

“不学会委托(Delegate),等于没学.NET编程!”

例程1-委托类型变量

using System;

namespace ConsoleApp1
{
    class Program
    {
        // 1. 定义一个委托类型
        public delegate int MathOptDelegate(int value1, int value2);

        public static int add(int a, int b)
        {
            return a + b;
        }
        
        static void Main(string[] args)
        {
            // 2. 委托类型变量可以接收一个方法引用(实例方法、静态方法都可以)
            MathOptDelegate mathOpt = Program.add;

            Console.WriteLine(mathOpt(1, 2)); // => 3

            Console.ReadKey();
        }
    }
}

/

例程2-以委托变量作为参数的方法

using System;

namespace ConsoleApp1
{
    class Program
    {
        // 1. 定义一个委托类型
        public delegate void doSomething();

        // 2. 定义一个以委托类型变量作为参数的方法
        public static void sampleMethod(doSomething doSomething)
        {
            Console.WriteLine("begin to do something.");
            doSomething();
            Console.WriteLine("stop doing something.");
        }

        // 3. 定义一个与委托类型匹配的方法
        public static void sayHello()
        {
            Console.WriteLine("hello");
        }
        static void Main(string[] args)
        {
            sampleMethod(sayHello);
            Console.ReadKey();
            // => begin to do something.
            // => hello
            // => stop doing something.
        }
    }
}

/

例程3-委托调用列表(多路委托)

using System;

namespace ConsoleApp1
{
    class Program
    {
        // 1. 定义一个委托类型
        public delegate void doSomething();

        // 2. 定义2个与委托类型匹配的方法
        static void SayHello() => Console.WriteLine("hello");

        static void SayGoodbye() => Console.WriteLine("Goodbye");

        static void Main(string[] args)
        {
            doSomething doSomething = SayHello;
            doSomething += SayGoodbye;
            doSomething();
            // => hello
            // => Goodbye
            Console.WriteLine(doSomething.GetInvocationList().Length);
            // => 2
            doSomething -= SayHello;
            doSomething -= SayHello;
            doSomething -= SayHello;
            doSomething();
            // => Goodbye
            Console.ReadKey();
            // PS. 若有返回值,则委托变量的返回值是最后调用方法的返回值
        }
    }
}

 

Click事件探究

.NET的事件响应机制也是用委托来实现的,以实现Click事件为例,大概分为如下几个步骤↓

1、定义一个委托类型(该类型被定义在System命名空间中)

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

2、声明一个委托类型变量(该变量被定义在相应组件中)

public event EventHandler Click;

加event和不加event的区别在于,加了event,事件只能由事件源对象激发,外界无法通过访问该变量激发。

3、挂载事件

this.button2.Click += new System.EventHandler(this.button2_Click);

button2_Click满足EventHandler的规范:

        private void button2_Click(object sender, EventArgs e)
        {
        }

/

技术图片

例程-动态挂载响应方法

using System;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void resp1(object sender, EventArgs e)
        {
            MessageBox.Show("响应1");
        }

        private void resp2(object sender, EventArgs e)
        {
            MessageBox.Show("响应2");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            button3.Click -= resp2;
            button3.Click -= resp1; // 防止累加
            button3.Click += resp1;
            // 上面为简单写法,
            // 等价写法:button3.Click += new EventHandler(resp1);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            button3.Click -= resp1;
            button3.Click -= resp2; // 防止累加
            button3.Click += resp2;
        }
    }
}

以上是关于C sharp #006# 委托与事件的主要内容,如果未能解决你的问题,请参考以下文章

C#委托与事件初探

如何在 Web App 和 C Sharp 之间进行通信

C# 从1到Core--委托与事件

C sharp实例:华盾武器门数据接收和解析

对“xxx”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。 错误解决一例。(代码片段

C#事件与委托详解