using System;
using System.Collections.Generic;
using System.Text;

/// <summary>
/// 功能:委托链的测试
/// 异常:无
/// 作者:FengWei

/// 日期:2007-06-23
/// </summary>
namespace Lesson63
{
    //一、定义委托
    public delegate void MethodHandler(string str);

    class DelegateChain
    {
        //二、定义委托调用的方法
        public static void MethodA(string str)
        {
            Console.WriteLine("MethodA-->" + str);
        }

        //二、定义委托调用的方法
        public static void MethodB(string str)
        {
            Console.WriteLine("MethodB-->" + str);
        }

        //二、定义委托调用的方法
        public static void MethodC(string str)
        {
            Console.WriteLine("MethodC-->" + str);
        }

        static void Main(string[] args)
        {
            //三、定义委托对象
            MethodHandler call = null;

            call += new MethodHandler(MethodA);
            call += new MethodHandler(MethodB);
            call += new MethodHandler(MethodC);

            //四、委托方法被调用
            call("委托方法被调用");

            Console.ReadLine();
        }
    }
}

 


 

using System;
using System.Collections.Generic;
using System.Text;

/// <summary>
/// 功能:委托的测试
/// 异常:无
/// 作者:FengWei
/// 日期:2007-06-23
/// </summary>
namespace Lesson63
{
    //第一步:定义委托
    //public delegate void MethodHandler(string name);

    class DelegateTest
    {
        //第二步:定义运行时预调用的方法 MethodA
        public static void MethodA(string name)
        {
            Console.WriteLine("MethodA-->" + name);
        }

        //第二步:定义运行时预调用的方法 MethodB
        public static void MethodB(string name)
        {
            Console.WriteLine("MethodB-->" + name);
        }

        //第二步:定义运行时预调用的方法 MethodC
        public static void MethodC(string name)
        {
            Console.WriteLine("MethodC-->" + name);
        }

        public static void Main()
        {
            //第三步:委托与方法相联系(创建delegate类型实例,传入预调用

                      的方法
            MethodHandler callA = new MethodHandler(MethodA);
            MethodHandler callB = new MethodHandler(MethodB);
            MethodHandler callC = new MethodHandler(MethodC);

            //第四步:委托调用方法
            callA("MethodA被调用");
            callB("MethodB被调用");
            callC("MethodC被调用");

            Console.ReadLine();
        }
    }
}

 


 

using System;
using System.Collections.Generic;
using System.Text;

/// <summary>
/// 功能:多点传送(同一事件的处理采用多个方法实现)
/// 异常:无
/// 作者:FengWei
/// 日期:2007-06-23
/// </summary>
namespace Lesson63
{
    //定义委托
    public delegate void MyMethodHandler(int i);

    public class MyEvent
    {
        //定义事件
        public event MyMethodHandler SomeEvent;
       
        //定义方法来触发事件
        public void onSomeEvent(int i)
        {
            if(SomeEvent!=null)
            {
                //触发事件
                SomeEvent(i);
            }
        }
    }

    class X
    {
        //被委托的方法
        public void ShowX(int i)
        {
            Console.WriteLine("ShowX()-->" + i);
        }
    }

    class Y
    {
        //被委托的方法
        public void ShowY(int i)
        {
            Console.WriteLine("ShowY()-->" + i);
        }
    }

    class Run
    {
        public static void RunShow(int i)
        {
             Console.WriteLine("RunShow()-->" + i);
        }

        public static void Main()
        {
            X x = new X();
            Y y = new Y();
            MyEvent myEvent = new MyEvent();

            //多点注册
            myEvent.SomeEvent+=new MyMethodHandler(RunShow);
            myEvent.SomeEvent+=new MyMethodHandler(x.ShowX);
            myEvent.SomeEvent += new MyMethodHandler(y.ShowY);
            Console.WriteLine("注册了三个方法RunShow ShowX ShowY");

            //调用触发事件的方法
            myEvent.onSomeEvent(8);

            //取消一个注册
            myEvent.SomeEvent -= new MyMethodHandler(y.ShowY);
            Console.WriteLine("注销了y.ShowY方法后");

            //调用触发事件的方法
            myEvent.onSomeEvent(6);

            Console.ReadLine();
 

础:
    1. .net框架约定,所有保存事件信息的类型都应该继承自System.EventArgs,并且类型名称应该以EventArgs结尾;委托类型应该以EventHandler结束,回调方法原型应该有一个void返回值,并且接受两个参数, 第一个Object指向发送通知的对象;第二个参数继随自EventArgs类型,包括接受者需要的附加信息。
     2.如果定义的事件没有传递 给事件接收者的附加信息,便不必定义新的委托,直接使用System.EventHandler,并将EventArgs.Empty传递给第2个参数即可
public delegate void EventHandler(Object sender, EventArgs e);

.net框架程序设计
最简间的事件与委托关联

C#委托及委托链//定义委托
C#委托及委托链
public delegate void RequestHandler(string Url);
C#委托及委托链
//定义委托类型的事件
C#委托及委托链
public event RequestHandler RequestEvent;
C#委托及委托链
//定义事件处理程序,即委托的回调方法
C#委托及委托链
public void RequestMothed(string url)
RequestEvent(stringTest);

事件可用的修饰符:

Static   Virtual    Override    Abstract

Static类似于字段,类的甩的对象共享静态事件,当引用这类事件时,必须用类名称而不是名称


一:登记事件
定义一个收邮件的类MailManager,在MailManager中定义一个收到邮件便触发的事件MailMSG,传真fax寻呼pager等对象在登记MailManager和MailMSG事件,当新电子邮件到达时,MailManager将通知发送给所有登记对象,这些对象按自己的方法处理。  开始代码.

C#委托及委托链class MailManager
}

其中C#委托及委托链   编辑器编译public event MailMsgEventHandler MailMsg;时,会产生
二:侦听事件

C#委托及委托链class Fax
}


其中,编辑器处理mm.MailMsg += new MailManager.MailMsgEventHandler(FaxMsg);
时会将它转换为

C#委托及委托链mm.add_MailMsg(new MailManager.MailMsgEventHandler(FaxMsg));
C#委托及委托链
//调用了前面public event MailMsgEventHandler MailMsg编辑的产生的代码  public virtual void add_MailMsg()方法,所以此方法里面有一个是MailMsgEventHandler委托的实例。


三:显式控制事件注册,实际上就将public event MailMsgEventHandler MailMsg编辑时产生的内部代码源码化

C#委托及委托链Class MailManager

至于为什么要用委托,可以从上面看出,它是类型安全的,因为一个函数指针的非正常调用可能会有未知的实现。

事件的发生只会激发某个动作(如果有),而具体要做什么,这就是委托实例的调用列表中的方法的执行。两者从概念上讲没有共同点。所以你没区分清楚是因为还没有真正理解它们重要的用途。
委托链
      委托的Invoke()方法,在委托链上,具有调用一个委托对象之前的委托对象(如果存在)的能力,这样,可以确保委托链上所有的委托对象都得到调用。但它的缺点是:只能取得最后一个调用对象的返回值,而前面调用对象的返回值都会丢失;另外,如果中间有一个委托对象产生异常或阻塞很长的时间,则会阻止其后面所有的委托对象的调用,因为委托链上的对象是按序调用的。
针对此种情况,MulticastDelegate类提供一个实例方法:GetInvocationList(),它返回一个委托形式的数组,从而可以任意调用委托链上的对象。

C#委托及委托链using System;
C#委托及委托链
using System.Text;
C#委托及委托链
C#委托及委托链
namespace delegateStudy

相关文章: