一、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. python字符串str和字节数组相互转化

    b = b"Hello, world!" # bytes object s = "Hello, world!" # str object print('str ...

  2. 使用Spring.net中对Ado.net的抽象封装来访问数据库

    使用Spring.net中对Ado.net的抽象封装来访问数据库     Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入 ...

  3. Java Concurrency in Practice 读书笔记 第二章

    第二章的思维导图(代码迟点补上):

  4. Eclipse系列: Eclipse设置Tomcat启动超时时间

    在eclipse的workspace目录下,找到如下文件: .metadata\.plugins\org.eclipse.wst.server.core\servers.xml 如下图所示,然后将它修 ...

  5. 从0开始学Java——@override的作用

    早上跟着<jsp&Servlet学习笔记>来学习jsp,在使用eclipse创建了一个servlet类之后,发现自动创建的类和书上相比,doGet方法的前面少了@override, ...

  6. Linux第二次学习笔记

    #Linux第二次实验(第三周) 学习目标 熟悉Linux系统下的开发环境 熟悉vi的基本操作 熟悉gcc编译器的基本原理 熟练使用gcc编译器的常用选项 熟练使用gdb调试技术 熟悉makefile ...

  7. 浅析Javascript

    Javascript是一种脚本语言,从出生就被唾弃,一开始人们使用它只是为了解决诸如页面数据校验之类的问题.它基于prototype的面向对象实现一度被认为很丑很难用,甚至很多身处一线Web开发者都不 ...

  8. Pivot的SelectionChanged事件绑定到VM的Command

    我要实现的是页面加载时,只获取SelectedIndex=0的数据,然后根据Pivot的SelectionChanged动态获取其他项的数据,我用的是MVVM的Command的方式,不想用后台注册事件 ...

  9. Unity 3D本地发布WebPlayer版时Failed to download data file解决方案

    遇到这个问题就是指Web服务器并没有支持这种*.unity3d文件类型.需要做的是在Web服务器中添加MIME类型: IIS 7 及以上版本: 在功能视图的IIS选项卡中: 双击打开MIME,选择添加 ...

  10. 第一章 : javaScript框架分类及主要功能

      从内部架构和理念划分,目前JavaScript框架可以划分为5类. 第一种是以命名空间为导向的类库或框架,如果创建一个数组用new Array(),生成一个对象用new Object(),完全的j ...