委托和事件

原创 2013年12月09日 15:05:03

一、委托

1.委托是一种特殊的对象类型(所以委托不可以定义在接口中),他的特殊之处在于,我们以前定义的所有对象都包含数据,而委托包含的只是方法的细节;

2.可以将委托当作类来理解,当使用类时,我们首先要定义一个类,再实例化一个类,即创建类的一个对象。同样,使用委托也需要经过这样的过程。定义委托就是告诉编译器这种类型代表了哪种类型的方法(通过方法签名确定),然后创建该委托的一个或多个实例;

3.理解委托的一种好方式是把委托当作给方法特征指定一个名称,也就是说任何一个方法(实例方法或静态方法),只要他的特征满足委托的定义,从理论上来说就可以通过这个委托来引用这个方法;

4.定义一个委托其实质就是定义一个新类(委托是派生于基类System.Delegate的一个类的实例),所以可以在定义类的任何地方定义委托,甚至可以在名称空间中把委托定义为顶层对象;

5.类创建的实例我们称之为“对象”,但是委托创建的实例,我们任然称之为委托;

6.委托在语法上总是带有一个参数构造函数,这个参数就是委托引用的方法,这个方法必须匹配最初定义委托时的签名;

7.委托既可以引用静态方法,又可以引用实例方法,只要方法的特征匹配委托的特征即可;

8.委托可以包含多个方法,这种委托称为多点委托;

9.委托可以识别+和+=运算符,他可以将方法添加到委托列表中,同样也可以识别-和-=运算符,他可以将方法从委托列表中移除;

10.有了委托就可以将方法当参数来进行传递;

namespace EventDel
{
    //定义一个委托。委托可以定义在任意位置,包括定义在类的外面
    public delegate int AddDelegate(int a, int b);

    public class Program
    {
        static void Main(string[] args)
        {
            //实例化一个委托
            AddDelegate addDel = new AddDelegate(Decrease);           
            //委托调用。
            Console.WriteLine(addDel(2, 5));

            //以下两种方式都可以
            //addDel += new AddDelegate(Add);
            addDel += Add;
            //打印出-3和7,因为他依次执行了Decrease方法和Add方法
            Console.WriteLine(addDel(2, 5));
            //返回7,因为他将先执行的Decrease方法的返回值覆盖掉了
            int iResult = addDel(2, 5);

            //返回每一个委托方法的返回值
            Delegate[] delegateList = addDel.GetInvocationList();
            foreach (var list in delegateList)
            {
                object result = list.DynamicInvoke(8, 9);
                Console.WriteLine(result);
            }
            //将该委托从该委托列表移除
            addDel -= new AddDelegate(Decrease);
            Console.WriteLine(addDel(2, 5));

            //将方法当着参数传递给委托
            int iResultTest = Test.Sum(Add);
            Console.WriteLine(iResultTest);

            Console.ReadLine();
        }

        public static int Add(int a, int b)
        {
            return a + b;
        }

        public static int Decrease(int a, int b)
        {
            return a - b;
        }
    }

    public class Test
    {
        public static int Sum(AddDelegate addDel)
        {
            return addDel(7,9);
        }
    }
}

二、事件

1.C#中事件经常被用到,一提到事件必然会和委托有联系。例如,Button按钮的Click事件,我们不需要定义对应的委托,那是因为微软将他封装好了,我们只需要调用即可,但是自定义事件就必须要定义相应的委托;

2.C#中的事件遵循“发布——订阅”的设计模式,在这种模式中,一个类公布能够出现的事件,然后任意数量的类都可以预定这个事件,一旦事件产生,运行环境就负责通知每个订户,告诉他们事件已经发生了,然后去执行对应的方法;

3.事件处理一般有一下几个步骤:

        1、声明事件委托。

        2、声明事件。

        3、添加事件的触发方法。

        4、添加事件的处理程序(响应事件的方法)。

        5、将指定的事件处理程序邦定到要处理的事件上(订阅事件)。

        6、用户信息操作,并触发事件(调用事件的触发方法)。

        7、通过事件委托的回调,执行我们需要的事件处理程序。

    /// <summary>
    /// 事件参数类
    /// </summary>
    public class TestEventArgs:EventArgs
    {
        #region Construtor

        public TestEventArgs(string content)
        {
            this.strContent = content;
        }

        #endregion

        #region Properties

        public string strContent
        {
            get;
            set;
        }

        #endregion
    }
    /// <summary>
    /// 事件发生类
    /// </summary>
    public class DefineEvent
    {
        #region Fields

        //定义委托
        public delegate void TestEventHandler(object obj, TestEventArgs e);

        //定义事件
        public event TestEventHandler OnReceive;

        #endregion

        #region Constructor

        public DefineEvent()
        {
        }

        #endregion

        #region  Methods

        public void StartEvent(TestEventArgs e)
        {
            //触发事件
            OnReceive(this, e);
        }

        #endregion

    }
    /// <summary>
    /// 订阅事件类
    /// </summary>
    public class ReceiveEvent
    {
        #region  Contructor

        public ReceiveEvent(DefineEvent definEvent)
        {
            //订阅事件,只要满足该委托的方法都可以
            //definEvent.OnReceive += new DefineEvent.TestEventHandler(AnotherReceiveEvent.OnReceiveData);
            definEvent.OnReceive += new DefineEvent.TestEventHandler(OnReceiveData);
        }

        #endregion

        #region Methods

        public void OnReceiveData(object obj, TestEventArgs e)
        {
            Console.WriteLine("您输入的是:" + e.strContent);
        }

        #endregion
    }

    /// <summary>
    /// 另一个订阅事件类
    /// </summary>
    public class AnotherReceiveEvent
    {
        public AnotherReceiveEvent(DefineEvent definEvent)
        {
            definEvent.OnReceive += new DefineEvent.TestEventHandler(AnotherReceiveEvent.OnReceiveData);
        }

        public static void OnReceiveData(object obj, TestEventArgs e)
        {
            Console.WriteLine("您输入的内容是:" + e.strContent);
        }
    }
    public class Program
    {
        static void Main(string[] args)
        {
            string strContent = Console.ReadLine();
            if (!string.IsNullOrEmpty(strContent))
            {
                TestEventArgs testEventArgs = new TestEventArgs(strContent);
                DefineEvent defineEvent = new DefineEvent();
                //同一个事件可以被多个订户订阅,此处有两个类订阅了该事件
                ReceiveEvent receiveEvent = new ReceiveEvent(defineEvent);
                AnotherReceiveEvent test = new AnotherReceiveEvent(defineEvent);
                defineEvent.StartEvent(testEventArgs);             
            }

            Console.ReadLine();
        }
    }








版权声明:本文为博主原创文章,转载请注明出处。

事件与委托趣谈

 事件与委托似乎很难以理解,这是因为它们的使用方式与常用的编码有很大的差别,例如通常编写的都是同步代码,调用一个类型的方法,会即刻出现方法执行的结果,这是符合逻辑的。但在某些情况中,同步代码未必满足需...
  • chiangbt
  • chiangbt
  • 2008年01月17日 21:51
  • 26584

委托和事件的区别(讲的很详细)

原文地址:http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx 委托 和 事件在 .Net F...
  • chopper7278
  • chopper7278
  • 2008年10月25日 23:58
  • 12381

快速理解C#中的委托与事件

以下内容只是个人理解,仅供参考。 什么是委托? 先看最简单的委托例子: namespace DelegateTest { public delegate void MessageDele...
  • Wiiix
  • Wiiix
  • 2016年05月20日 20:02
  • 5599

通俗易懂地解释一下C#中的事件和委托

作者:吴杰 链接:http://www.zhihu.com/question/21638630/answer/26061308 来源:知乎 著作权归作者所有,转载请联系作者获得授权。 如果...
  • wonengguwozai
  • wonengguwozai
  • 2016年09月10日 19:20
  • 526

C# 中的委托和事件(详解)

C# 中的委托和事件        委托和事件在 .NET Framework 中的应用非常广泛,然而,较好地理解委托和事件对很多接触 C# 时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛...
  • ZXD9790902
  • ZXD9790902
  • 2016年09月29日 09:10
  • 362

C# .Net 委托和事件的区别

   在.net中,事件是一种特殊的委托,那他到底特殊在哪,换句话说,加上event关键字到底有什么用,我理解主要有两方面,下面用实例说明:    一 、事件只能在本类型内部“触发”,委托不管在本类型...
  • azkaser
  • azkaser
  • 2009年11月24日 15:18
  • 8881

【C#】C#委托和事件的实例讲解

using System; namespace delegate_event { // 定义一个猫类 class Cat { // 定义一个名字字段 private string na...
  • sinat_20559947
  • sinat_20559947
  • 2015年07月22日 15:33
  • 4024

java实现事件委托

事件委托 委托
  • shuciqi
  • shuciqi
  • 2014年05月13日 14:27
  • 2387

Unity中对于委托、事件的应用

[引言] 这边文章主要是针对刚踏入这行的程序员,是我工作半年多来积累下来的一些经验,仅作为参考,也希望各位经验丰富的前辈多批评指正。 我是专科生毕业,我们学校所教的C#的内容其实只有非常非常基础的那些...
  • GhostOrange
  • GhostOrange
  • 2016年11月13日 18:01
  • 2351

委托、事件、单例在Unity3D中的使用

原文 请点击这里 翻译:claudioHere I demonstrate how to create delegates, events and singletons to work in con...
  • arbut
  • arbut
  • 2015年03月11日 19:51
  • 3050
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:委托和事件
举报原因:
原因补充:

(最多只允许输入30个字)