一、Delegate委托可以理解为一个方法签名。

    可以将方法作为另外一个方法的参数带入其中进行运算。在C#中我们有三种方式去创建委托,分别如下:

public delegate void Print(string str);

static void delegatemethod(string str)
        {
            Console.WriteLine(str);
        }

public static void Main()
        {
            #region 委托
            //1.普通委托
            var print1 = new Print(delegatemethod);
            print1("这是普通方式创建的委托");
            //2.匿名委托
            Print print2 = delegate(string str) {
                Console.WriteLine(str);
            };
            print2("这是匿名方式创建的委托");
            //3.lambda委托
            Print print3 = (string str) => {
                Console.WriteLine(str);
            };
         }

二、Event事件,是一种封装过的委托。

    它拥有以下三要素:

    1.事件发行者-达到某些条件时激发事件的对象

    2.事件订阅者-订阅事件并对事件发生时进行处理的对象

    3.定义发行者和订阅者关系,一个发行者可能会有多个订阅者。

  三、事件和委托的区别

    1.委托允许直接通过委托去访问相应的处理函数,而事件只能通过公布的回调函数去调用

    2.事件只能通过“+=”,“-=”方式注册和取消订户处理函数,而委托除此之外还可以使用“=”直接赋值处理函数。

  最后我们可以看看整个自定义事件的处理办法以及事件和委托的区别如下代码:

//事件参数
    public class My_EventArgs : EventArgs
    {
        private string _args = string.Empty;
        public My_EventArgs(string args)
        {
            _args = args;
        }
        public string Args
        {
            get { return _args; }
        }
    }

//事件发行者
    public class SourceClass
    {
        public double Width { get; set; }
        public double Height { get; set; }

My_EventArgs Evargs;
        public SourceClass(string args)
        {
            Evargs = new My_EventArgs(args);
        }
        //定义委托
        public delegate void EventHandler(object sender, My_EventArgs args);

#region 使用委托方式声明
        public EventHandler Clicked;
        public void ClickedAsync()
        {
            if (Clicked != null)
            {
                Clicked(this, Evargs);
            }
        }
        #endregion
        #region 使用事件方式声明
        public event EventHandler Click;
        public void ClickAsync()
        {
            if (Click != null)
            {
                Click(this, Evargs);
            }
        }
        #endregion
    }
    //事件订阅者
    public class Del
    {
        public delegate void Print(string str);

static void delegatemethod(string str)
        {
            Console.WriteLine(str);
        }

public static void Main()
        {
            #region 委托
            //1.普通委托
            var print1 = new Print(delegatemethod);
            print1("这是普通方式创建的委托");
            //2.匿名委托
            Print print2 = delegate(string str) {
                Console.WriteLine(str);
            };
            print2("这是匿名方式创建的委托");
            //3.lambda委托
            Print print3 = (string str) => {
                Console.WriteLine(str);
            };
            print3("这是lambda方式创建的委托");
            #endregion

#region 事件
            SourceClass source = new SourceClass("我的事件被触发");
            source.Width = 5.0;
            source.Height = 3.0;
            //一、委托方式允许source.Clicked(source, new My_EventArgs("我使用委托方式调用的Args"));调用
            source.Clicked = new SourceClass.EventHandler(source_RightClick);
            source.Clicked += new SourceClass.EventHandler(source_LeftClick);
            source.ClickedAsync();
            source.Clicked(source, new My_EventArgs("我使用委托方式调用的Args"));
            //二、很明显用户希望通过使用source.ClickedAsync();去调用函数,而非直接使用上行代码去调用,所以在这里需要使用Event关键字进行申明
            //注1.事件方式不允许source.Clicked(source, new My_EventArgs("我使用委托方式调用的Args"));直接调用
            //注2.事件不允许 source.Click = new SourceClass.EventHandler(source_LeftClick);直接赋值
            source.Click += new SourceClass.EventHandler(source_LeftClick);
            source.ClickAsync();
            //注销事件和注册事件
            source.Click -= new SourceClass.EventHandler(source_LeftClick);
            source.Click += new SourceClass.EventHandler(source_RightClick);
            source.ClickAsync();
            Console.ReadLine();
            #endregion
        }
        //事件处理方法1
        static void source_LeftClick(object sender, My_EventArgs args)
        {
            SourceClass source = sender as SourceClass;
            Console.WriteLine("目标宽度:" + source.Width + ",目标高度:" + source.Height);
            Console.WriteLine("目标对象参数:"+args.Args);
           
        }

//事件处理方法2
        static void source_RightClick(object sender, My_EventArgs args)
        {
            SourceClass source = sender as SourceClass;
            Console.WriteLine("目标面积:" + source.Width *source.Height);
        }
    }

运行的效果图如下:

C#中Delegate和Event以及它们的区别(转载)的更多相关文章

  1. C#知识点总结系列:3、C#中Delegate和Event以及它们的区别

    1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取锁之后因为异常,致锁 ...

  2. jQuery中delegate与on的用法与区别

    在jQuery1.7中 .delegate()已被.on()取代.对于早期版本,它仍然使用事件委托的最有效手段. 在事件绑定和委派,delegate()和on在一般情况下,这两种方法是等效的. .de ...

  3. C#知识点总结系列:3、C#中Delegate和Event

    一.Delegate委托可以理解为一个方法签名. 可以将方法作为另外一个方法的参数带入其中进行运算.在C#中我们有三种方式去创建委托,分别如下: public delegate void Print( ...

  4. php中global与$GLOBALS的用法及区别-转载

    php中global 与 $GLOBALS[""] 差别 原本觉得global和$GLOBALS除了写法不一样觉得,其他都一样,可是在实际利用中发现2者的差别还是很大的! 先看下面 ...

  5. Java中List、Set和Map的区别--转载

    List按对象进入的顺序保存对象,不做排序或编辑操作.Set对每个对象只接受一次,并使用自己内部的排序方法(通常,你只关心某个元素是否属于Set,而不关心它的顺序--否则应该使用List).Map同样 ...

  6. Java中print、printf、println的区别(转载)

    printf主要是继承了C语言的printf的一些特性,可以进行格式化输出 print就是一般的标准输出,但是不换行 println和print基本没什么差别,就是最后会换行 System.out.p ...

  7. SQL中on条件与where条件的区别(转载)

    数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. 在使用left jion时,on和where条件的区别如下: 1. on条件是在生成临时表时使用的条 ...

  8. css中单位px和em,rem的区别[转载]

    PX特点 1. IE无法调整那些使用px作为单位的字体大小: 2. 国外的大部分网站能够调整的原因在于其使用了em或rem作为字体单位: 3. Firefox能够调整px和em,rem,但是96%以上 ...

  9. JavaScript中var、let和const的区别(转载)

    一.前言 在ES6(ES2015)出现之前,JavaScript中声明变量就只有通过 var 关键字,函数声明是通过 function 关键字,而在ES6之后,声明的方式有 var . let . c ...

随机推荐

  1. Web 服务编程,REST 与 SOAP(转)

    原文地址:Web 服务编程,REST 与 SOAP REST 简介 在开始我们的正式讨论之前,让我们简单看一下 REST 的定义. REST(Representational State Transf ...

  2. js屏蔽回车键

    document.onkeydown = function () {            if (window.event && window.event.keyCode == 13 ...

  3. Android屏蔽返回键

    @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode==KeyEvent.KEYCODE_BACK) ...

  4. 无光驱安装原版 windows server2008,win7 的方法,64位的。

    这几天要对一台服务器进行安装 windows server2008的系统,64位.尼玛在网上买了一个光驱迟迟不到所以只能用U盘来了 以前安装ghost的系统U盘分分钟搞定.安装原版的iso文件遇到了一 ...

  5. 深入探索Java 8 Lambda表达式

    2014年3月,Java 8发布,Lambda表达式作为一项重要的特性随之而来.或许现在你已经在使用Lambda表达式来书写简洁灵活的代码.比如,你可以使用Lambda表达式和新增的流相关的API,完 ...

  6. Shadowsock搭建

    搭建Shadowsocks服务端: 搭建Shadowsocks之前首先必须购买一个VPS.一般VPS提供商会给一个测试地址,购买之前最好先ping一下速度.也可以通过以下网址测试下vps网络速度: h ...

  7. ThinkPHP之项目搭建

    前言 在做javaweb开发时,我们创建一个项目,MyEclipse会自动为我们生成相应的目录结构,我们在此结构上才进行web开发,在使用TinkPHP框架做PHP开发时,一样,我们如何生成一个标准的 ...

  8. Javascript基础系列之(一)JavaScript语法

    javascript的语法 1.区分大小写 javascript中,变量.函数.运算符都区分大小写. 2.弱类型变量 定义变量只用 "var"关键字 var age = 25; v ...

  9. window下为apache配置ssl证书

    转载自 子非鱼 的博客稍作修改 第一步:依赖 配置Apache服务器支持https协议和SSL证书,最基本的要求是Apache包含openssl模块.还好apache/bin目录下有libeay32. ...

  10. struts2支持的结果类型

    在struts2-core.jar/struts-default.xml中,我们可以找到关于result-type的一些配置信息,从中可以看出struts2组件默认为我们提供了这 些result-ty ...