C#委托、事件、多播

委托:

什么是委托:

 委托是用户自定义类型,这一点和类,接口等一样的。委托是引用类型。

委托指向一系列具有相同签名和返回类型的方法的地址。

调用委托的时候,它所包含的所有方法都会被执行。

可以理解为用来存储方法,委托就是用来存储方法的一种解决方案。

现实中:张三委托李四去做一件事。站在张三的角度,张三委托了李四,站在李四的角度,李四是张三的代理。

委托的本质:

委托其实是将一个方法作为参数传递给另一个方法。(委托可以充当方法的回调函数的类型)。

委托是方法的引用。(即委托是方法的代理)。

委托可以引用多个方法。(如:多播委托)。

可以把委托理解成一系列方法的代理,调用委托就相当于调用了一系列的方法。

委托如何定义:

使用delegate关键字定义

a.委托可以声明在类外部,也可以在类内部

b.跟方法有点类似,有参数,返回值,访问修饰符,比方法声明多一个关键字delegate

public delegate void SayHello()

创建委托的公式:

delegate 该委托存储的方法的返回值 委托的名字(该委托的方法的参数)

委托怎么使用/调用?

委托如何使用:

  • 通过new来实例化
  • 通过一个方法,这个是编译器提供的语法糖
  • 通过一个匿名委托
  • 拉姆达Lambda

实例化(让某个委托类型去代理一系列方法地址)

实例化有一种简写,只要方法满足委托的,就可以直接赋值给委托。

internal class Program
{
    public delegate void SayHello();

    static void Main(string[] args)
    {
        //实例化 (让某个委托类型去代理一系列方法地址) C#1.0写法
        SayHello sayHello = new SayHello(Method1);
        //调用
        sayHello();
        // 实例化有一种简写,只要方法满足委托的,就可以直接赋值给委托
        SayHello sayHello2 = Method2;
        //调用
        sayHello2();
    }
    public static void Method1() {
        Console.WriteLine("方法1");
    }
    public static void Method2()
    {
        Console.WriteLine("简写");
    }

}

 使用匿名委托进行实例化,匿名委托本质就是匿名方法(匿名函数:没有名称方法) C# 2.0 写法

匿名函数包括两种:1。匿名委托   2。Lambda拉姆达(表达式,语句)

    public delegate bool Delegate2(string arg);

    static void Main(string[] args)
    {
        Delegate2 delegate2 = Method3;  //代理非匿名方法

        //多播委托: 一个委托实例,同时代理多个方法地址。
        delegate2 += Method4;
        delegate2 -= Method3;

        Delegate2 delegate22 = delegate (string arg) {
            return arg == "hello";
        };
        delegate2("Method3");
        delegate22("Method4-hello");
    }
    public static bool Method3(string arg) {
        Console.WriteLine("方法3");
        return arg == "hello";
    }
    public static bool Method4(string arg) {
        Console.WriteLine("方法4");
        return true;
    }

}

委托如何调用:

(前两个比较常用)

a.委托实例名直接调用。
如:SayHello sayChinese = new SayHello(SayChinese);
sayChinese();
b.Inovke执行委托
​ 如果委托定义没有参数,则Inovke也没有参数;委托没有返回值,则Inovke也没有返回值
c.BeginInvoke开启一个新线程执行委托
​ NetCore不支持,NetFamework支持 NetCore有更好的多线程功能来支持实现类似功能d.EndInvoke等待BeginInvoke执行完成后再执行

事件:

什么是事件:

事件是用户操作,例如按键、单击、鼠标移动等。

在C#中,事件是一种特殊的委托,事件是基于委托的,即事件是某个委托的实例(简单理解:事件是由委托创建出来的变量而异)。

两个核心:

a.事件执行的时机  b.事件执行的业务逻辑
语言中事件,指委托的实例。把委托看作一种类型,而事件就是委托的个体(实例)
定义格式:public event  EventHandler clickEvent; 
WinForm窗体程序看到很多的事件类型(Click,MouseXXX,KeyXXX等),事件类型其实是不同的事件变量

事件是什么?

(1)事件是委托实例,增加一个关键字Event,是特殊的委托(用委托生成的一个变量而异)
(2)事件只能在当前类被访问,子类和类外部均不能执行类中的事件方法(安全)
(3)委托和事件从本质上来说没啥区别(事件基于委托,没有委托,就没事件。)

定义事件:

定义一个事件。使用event关键字。 EventHandler委托类型  MyClick就是委托实例,即事件变量。

public static event EventHandler MyClick;    // 默认值null

事件实例化(和委托实例化基本一致。只是第一初始化时,也可以使用+=或-=)

internal class Program
{
    // 定义一个事件。使用event关键字。 EventHandler委托类型  MyClick就是委托实例,即事件变量。
    public static event EventHandler MyClick;  // 默认值null

    static void Main(string[] args)
    {
        //定义事件?
        EventHandler click1 = new EventHandler((sender, arg) => { }); // 委托实例,不是事件

        //事件实例化(和委托实例化基本一致。只是第一初始化时,也可以使用 += 或 -=)
        MyClick = Program_MyClick;
        MyClick += Program_MyClick1;
        MyClick += delegate (object sender, EventArgs arg)
        {
            Console.WriteLine("匿名委托");
        };
        MyClick += (sender, arg) =>
        {
            Console.WriteLine("拉姆达语句");
        };
        //调用事件?
        MyClick.Invoke(null, null);
    }
    private static void Program_MyClick(object sender, EventArgs e)
    {
        Console.WriteLine("事件第一次赋值");
    }

    private static void Program_MyClick1(object sender, EventArgs e)
    {
        Console.WriteLine("事件第二次赋值");
    }

}

事件定义的位置:

类内部,不能在方法内部

事件本质:

事件本质:指委托的实例。事件肯定是委托,但委托不一定是事件。

事件是一种特殊的委托实例。特殊在哪里?安全的委托实例。

事件主要包括三个部分:

1. 事件的订阅者(控件,比如:Button,Button对于事件来说就是一个用户)
2. 事件的触发者(各种操作,比如:点击)
3. 订阅者和触发者之间的数据传输通道(事件句柄:一头连接着订阅者,一头连接着触发者)
报社:观察者,发布者
用户:订阅者,接收者
观察者 通知 订阅者 让订阅者做去做“事”

多播:

委托是一系列方法的引用,调用委托时,可以同时执行多个方法。
多播委托,就是用一个委托代理多个方法,调用委托时,可以执行多个方法。
多播委托的本质是运算符重载 += 、 -=
多播委托好处:广播事件(多次绑定事件,或者说绑定多个事件)。为了通知。

事件和委托的区别?

参考:

  1. 委托是类型,而事件不是。委托可以直接赋值给一个变量,而事件则需要通过加关键字event来声明,这样才能被赋值,并且只能通过+=和-=来进行注册和注销方法的操作。
  2. 委托是类型安全的,而事件不是。委托是强类型的,是方法的引用,只要方法的参数和返回值能够匹配委托,就可以赋值给委托。这是事件的灵活性之处,但也是风险,因为它不是类型安全的。
  3. 事件基于委托,事件提供了一种安全的方式来注册和触发事件,限制了对事件的注册和触发,只能通过+=,-=和raise(触发事件)操作。
  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值