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框架程序设计
最简间的事件与委托关联
//定义委托
public delegate void RequestHandler(string Url);
//定义委托类型的事件
public event RequestHandler RequestEvent;
//定义事件处理程序,即委托的回调方法
public void RequestMothed(string url)
RequestEvent(stringTest);
事件可用的修饰符:
Static Virtual Override Abstract
Static类似于字段,类的甩的对象共享静态事件,当引用这类事件时,必须用类名称而不是名称
一:登记事件
定义一个收邮件的类MailManager,在MailManager中定义一个收到邮件便触发的事件MailMSG,传真fax寻呼pager等对象在登记MailManager和MailMSG事件,当新电子邮件到达时,MailManager将通知发送给所有登记对象,这些对象按自己的方法处理。 开始代码.
class MailManager
}
其中
编辑器编译public event MailMsgEventHandler MailMsg;时,会产生
二:侦听事件
class Fax
}
其中,编辑器处理mm.MailMsg += new MailManager.MailMsgEventHandler(FaxMsg);
时会将它转换为
mm.add_MailMsg(new MailManager.MailMsgEventHandler(FaxMsg));
//调用了前面public event MailMsgEventHandler MailMsg编辑的产生的代码 public virtual void add_MailMsg()方法,所以此方法里面有一个是MailMsgEventHandler委托的实例。
三:显式控制事件注册,实际上就将public event MailMsgEventHandler MailMsg编辑时产生的内部代码源码化
Class MailManager

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

namespace delegateStudy