C#中的委托可以实现将方法本身作为参数传递,也就是说,委托是方法的引用,我们一旦为委托分配了方法,那这个委托就和这个方法具有完全相同的行为。委托对象的引用中包含一个指向这个方法的指针。通过委托把方法的引用封装到对象中,然后将委托对象传递给调用引用方法的代码。

与委托类型匹配的方法必须满足的条件:

两者具有相同的参数树木你,并且类型相同、顺序相同、参数的修饰符也相同。两者具有相同的返回类型。

定义实例方法Add,将该方法作为自定义类型FirstDelegate的匹配方法。在Program类中定义一个委托类型FirstDelegate,接着在Main中创建该委托类型实例fd,并绑定到Add方法。

public class Test{ public int Add(int a, int b){ return a+b; }}public delegate int FirstDelegate(int a, int b);//定义一个委托类型Main(){ Test t = new Test(); FirstDelegate fd = t;//创建委托类型fd并绑定到Add方法 int sum = fd(1,2);}


匿名方法:简化委托引用方法的过程

//定义一个委托类型delegate void Dele(int x);//用匿名方法创建委托Dele de = delegate(int x){ //委托所调用的代码。。。}


委托的发布和订阅(按书的说法如下):

首先要通过发布者来发布这个委托,然后定义一个事件触发器,在这个触发器被激发后,会调用这个委托,然后委托根据自身的订阅情况,再进行回调委托(事件)的处理方法,因为委托事件已经通过"+="符号链接到该处理方法上。

还是按例子进行说明~~

//定义一个委托类型Ring,参数传入1表示上课,2表示下课public delegate void Ring(int kind);/*定义委托发布者类型SchoolRing,并定义Ring类型的公有成员,再定义一个成员方法Active,用来实现激发委托操作*/public class SchoolRing{ pulbic Ring OnBell;//委托发布 public void Active(int kind){ if(kind==1||kind==2){//不为空说明已经订阅。回调OnBell委托所订阅的具体方法 if(OnBell!=null) OnBell(kind); }else{} }}

//定义订阅者类

public class Students{//定义订阅者类 public void Subscribe(SchoolRing sr){//学者订阅铃声这个委托事件 sr.OnBell += SchoolActive;//通过委托的链接操作进行订阅 } public void SchoolActive(int kind){ if(kind==1){} else if(kind==2){} } public void Cancel(SchoolRing sr){//取消订阅铃声动作 sr.OnBell -= SchoolActive; }}

//当发布者SchoolRing类的对象调用其Active方法进行打铃时,就会自动调用Students对象的SchoolActive这个事件处理方法

SchoolRing sr = new SchoolRing();//创建事件发布者实例Students st = new Students();//创建事件订阅者实例st.Subscribe(sr);//学生订阅学校铃声sr.Activte(Convert.ToInt32(Console.ReadLine()));//开始打铃


.NET类库中定义一个EventHandler类,并且尽量使用这类作为事件的委托类型,该委托类型的定义:

public delegate void EventHandler(object sender,EventArgs e);

其中object类型的参数sender表示引发事件的对象,由于事件成员只能由类型本身出发,所以通常传为this。

上面代码可修改为:

/*EventHandler委托的第二个参数e表示事件中包含的数据。如果发布者还要向订阅者传递额外的事件数据,需要定义EventArgs的派生类*/public class RingArgs: EventArgs{ private int kind; public int Kind{get{return kind;}} public RingArgs(int kind){this.kind = kind;}}//Students类对OnBell事件的处理方法修改public void SchoolActive(object sender, EventArgs e){ if(((RingArgs)e).Kind == 1){} else if(((RingArgs)e).Kind == 2){}}

//SchoolRing的实例在出发OnBell事件时,可以将该类型(RingArgs)的对象作为参数传递给EventHandler委托

public event EventHandler OnBell;//委托发布public void Active(int kind){ if(kind == 1 || kind ==2){ if(OnBell!=null) OnBell(this, new RingArgs(kind));//回调委托所订阅的方法 }}public void SchoolActive(object sender, EventArgs e){ if(((RingArgs)e).Kind == 2){} else if(...)}


//在之前讲到的Windows控件中其实也涉及到事件的内容,我们通常在Form1.cs中定义事件,在Form.Designer.cs中关联事件

private void button1_Click(object sender , EventArgs e){}button1.Click += new EventHandler(button1_Click);//关联事件