一、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. 使用Spring.net中对Ado.net的抽象封装来访问数据库

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

  2. JS 之高级函数

    作用域安全的构造函数 当使用new调用构造函数时,构造函数内部this对象会指向新创建的对象实例.如果不使用new,直接调用的话,则this对象会映射到window对象上.所以需要判断下. eg: f ...

  3. 各种python环境的问题

    [OS] mac [ERROR] decoder jpeg not available [SOLUTION] $ pip uninstall pillow $ brew install libjpeg ...

  4. 『设计』Laura.Compute 设计思路

    前言: 前一篇文章 <『开源』也顺手写一个 科学计算器:重磅开源> ,继 Laura.Compute 算法开源之后,有 博客园 园友 希望公开一下 Laura.Compute算法 的 设计 ...

  5. WebGame开发总结

    不知不觉我们的项目开发有2年了,这两年来走了很多弯路,也收获了很多,今天在这里做一个总结. 项目基本情况: 服务器端采用c++和c#混合开发,网络层采用c++开发,业务逻辑用c#开发.客户端采用sil ...

  6. Boostrap(2)

    网页布局 1.网格布局 网格布局就是把网页分为许多小格子,看起来像table,然后在每个小格子中放我们的内容.当然,我们也可以指定一片区域使用网格系统.网格布局主要是应用在移动设备上的,使用方法如下: ...

  7. 19.C#逐一介绍IEnumerable和IEnumerable<T>中的扩展方法(10.3-10.5)

    今天没有太多的言语,只有代码,扩展方法多得太多,不能一一列完,书中一些,看多了也就会使用了. //Enumerable.Range 返回起始到结束范围,是一个Enumrable<int>类 ...

  8. Beta 分工比例

    组员在Beta版本的分工和个人贡献百分比. 人员 任务完成情况 贡献比 031302331 闹钟,爬取知乎数据,书籍下载,解决bug,帮助队友 25% 031302442 注册登录逻辑,书籍评论评分页 ...

  9. session的一个问题

    <%@ page language="java" import="java.util.*,javax.servlet.http.Cookie.*" pag ...

  10. WPF--调用线程必须为 STA,因为许多 UI 组件都需要(转载)

    自VS2005开始,UI元素在不同线程中访问就受到限制了,当然你也可以解除这种限制 以下提供Framework3.0的解决方案发: public partial class Window1 : Win ...