首页 > 编程语言 >C#委托、事件、多播

C#委托、事件、多播

时间:2024-08-17 21:51:23浏览次数:12  
标签:多播 委托 C# MyClick 实例 static 事件 方法

委托:

什么是委托:

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

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

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

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

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

委托的本质:

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

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

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

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

委托如何定义:

使用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(触发事件)操作。

标签:多播,委托,C#,MyClick,实例,static,事件,方法
From: https://blog.csdn.net/2301_79849777/article/details/141283492

相关文章

  • Object Detection: Non-Maximum Suppression (NMS)
    ObjectDetection:Non-MaximumSuppression(NMS)https://kikaben.com/object-detection-non-maximum-suppression/ObjectdetectionmodelslikeYOLOv5andSSDpredictobjects’locationsbygeneratingboundingboxes(showninbluerectanglesbelow).However,......
  • [赛记] 暑假集训CSP提高模拟22 23
    连通块66pts老套路,删边改加边;但改完以后不知道怎么求最长路径了,当时也想到了维护直径,但不知道咋干;具体地,用并查集维护连通性,每次合并时需要维护新的直径,不难发现,新的直径的两个端点一定在原来的两个直径的四个端点中选;于是只有六种情况,枚举一下即可;我们要直径有啥用呢?当我们......
  • ncnn operators
    operatorshttps://github.com/Tencent/ncnn/blob/master/docs/developer-guide/operators.mdAbsValArgMaxBatchNormBiasBinaryOpBNLLCastCELUClipConcatConvolutionConvolution1DConvolution3DConvolutionDepthWiseConvolutionDepthWise1DConvolutionDepth......
  • Python 潮流周刊#65:CSV 有点糟糕(摘要)
    本周刊由Python猫出品,精心筛选国内外的250+信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进Python技术,并增长职业和副业的收入。分享了12篇文章,12个开源项目,全文2000字。以下是本期摘要:......
  • 在EFCore中多对多关系的设计数据插入与查询
    学生类StudentpublicclassStudent{publicintId{get;set;}publicstringName{get;set;}publicintAge{get;set;}publicList<Teacher>Teachers{get;set;}=newList<Teacher>();}老师类TeacherpublicclassTeacher{......
  • 题解:AtCoder Beginner Contest 367
    总体情况A题意在AtCoder王国,居民们每天都要在\(A\)点大声喊出他们对章鱼烧的热爱。住在AtCoder王国的高桥每天\(B\)点睡觉,\(C\)点起床(\(24\)小时钟)。他醒着的时候可以喊出对章鱼烧的爱,但睡着的时候却不能。判断他是否每天都能喊出对章鱼烧的爱。这里,一天有\(24......
  • Plateau-Rayleigh 不稳定性 + Young-Laplace 方程
    考虑竖直下落水柱中的\(AB\)两点\[\begin{matrix}\displaystyle\frac12\rhoU_0^2+\rhogz+P_A=\frac12\rhoU^2(z)+P_B\\[2ex]\displaystyle\nabla\cdotn=\frac1{R_1}+\frac1{R_2}\approx\frac1r\\[2.5ex]\displaystyleP_A\approxP_0+\frac\gammaa,......
  • Lucas-Washburn + Cassie-Baxter
    如果粉末间隙内壁的表面能随着润湿而降低,则液体会向管内上升渗入(\(\gamma_{\text{SL}}<\gamma_{\text{SO}}\))。考虑液体上升的驱动力来自于附加压力,则由弯曲表面附加压力Young-Laplace方程,驱动力为:\[F=pS=\frac{2\gamma\cos\theta}R\piR^2=2\piR\gamma\cos\theta\]间隙内的......
  • Lambert cos 定律再积分无穷级数求和
    设有能量为\(I\)的一束光射向表面\(s\),发生理想的漫反射。设反射率为\(a\),则\(s\)向在\(\phi\)方向反射的能量\(R\)可由Lambertcos定律给出:\[R_\varphi=\frac{aI}\pi\cos\varphi\cdots\]在漫反射的全部能量中,位于全反射临界角\(\varPsi\)形成的锥体以内的能量可......
  • 【C++小白到大牛】红黑树那些事儿
    目录前言:一、红黑树的概念二、红黑树的性质三、红黑树结点的定义四、红黑树的插入情况一:u存在且为红情况二:u不存在/u存在且为黑小总结:原码:五、红黑树的检验六、性能比较前言:我们之前已经学过了二叉搜索树的优化版——AVL树,这次我们来学习二叉搜索树的另外一种优......