1.委托
委托的声明原型是
delegate <函数返回类型> <委托名> (<函数参数>)
例如:public delegate void Calculator(int i, int j);
这样就定义了一个委托,但是委托在.net内相当于声明了一个类,类如果不实例化为对象,很多功能是没有办法使用的,委托也是如此.
下面,直接来定义一个委托,并且来使用委托。
namespace _delegate
{
public delegate void Calculator(int i, int j);//定义委托Compute,两个参数i和j;方法签名和加减法一样。无非是多加了一个delegate关键字。
public class DelegateCal
{
private static void Add(int i, int j)//声明加法
{
Console.WriteLine("{0}", i + j);
}
private static void Sub(int i, int j)//声明减法
{
Console.WriteLine("{0}", i - j);
}
private static void Calculator(int i, int j, Calculator Cal)//Calculator这个方法有三个参数,第三个Compute是之前定义的委托类型。
{
Cal(i, j); //委托类型Compute定义的一个Cal变量。在给Cal赋值的时候动态地决定使用哪个方法
}
//委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递。
/*static void Main(string[] args)
{
Calculator(2, 5, Add);
Calculator(5, 2, Sub);
Console.ReadLine();
}*/
//从此可以看出Compute和int都是数据类型,那么是不是可以定义两个变量,把方法赋给变量。
static void Main(string[] args)
{
//将方法绑定到委托
/*Compute delegate1, delegate2;
delegate1 = Add;
delegate2 = Sub;
Calculator(1,2, delegate1);//3
Calculator(7,4, delegate2);//3
Console.ReadLine();
*/
//其实,委托还有一个特性不同于int或其他数据类型,它可以将多个方法绑定到同一个委托上。如下:
/*Compute delegate1;
delegate1 = Add;
delegate1 += Sub;
Calculator(5, 1, delegate1);
Console.ReadLine(); //先输出加法为6,后输出减法为4;
*/
//其实,我们可以不用Calculator方法,通过委托来直接调用Add方法或者Sub方法。如下:
Calculator delegate1;
delegate1 = Add;
delegate1 += Sub;
delegate1(9, 2);
Console.ReadLine();//和为11、差为7
}
}
}
2.事件
了解了委托之后,咱们来讲一下事件。
C#中事件的定义和委托的声明其实是非常的相似:
event <委托类型> 事件名
例如: public event Computer OnComputer;//定义事件,将其与代理绑定
声明了事件之后就可以实例化这个事件,注册函数到事件中。
下面咱用一个例子来说明:
namespace _delegate
{
public delegate void Computer(); //首先声明一个委托。
public class EventCal
{
public event Computer OnComputer;//定义事件,将其与代理绑定
public virtual void FireEvent()//触发事件的方法
{
if (OnComputer != null)
{
OnComputer(); //触发事件
}
}
}
public class Compere //主持人
{
public void EventHandler()//事件处理函数
{
int a = 1;
int b = 1;
int c = a + b;
Console.WriteLine("a+b={0}",c);
}
public static void Main()
{
EventCal ec = new EventCal();
Compere c = new Compere();
ec.OnComputer += new Computer(c.EventHandler);//注册
ec.FireEvent();
Console.Read();
}
}
}
EventCal类相当于一个时间发布者,它定义了事件的相关信息,包括定义了一个事件用于计算(OnComputer),以及一个触发事件的函数(FireEvent())
Compere类则相当于一个事件订阅者,或者说叫做主持人吧。它定义了一个事件处理函数(EventHandle()),并用+=将其与事件联系起来。从而使事件触发的时候能够调用我这个方法,其实就是计算一下a+b的值。
注意:事件处理函数的方法签名要与代理的方法签名相同,这是非常重要的一点
namespace _delegate
{
public delegate void Computer(object sender, MyEventArgs e);//sender 产生事件的对象,e 事件的参数
public class EventCal
{
public event Computer OnComputer;//定义事件,将其与代理绑定
public virtual void FireEvent(MyEventArgs e)//触发事件的方法
{
if (OnComputer != null)
{
OnComputer(this,e); //触发事件
}
}
}
public class MyEventArgs : EventArgs//定义事件参数类
{
public readonly int _a,_b;
public MyEventArgs(int a,int b)//这是一个构造函数,参数列表为int a,int b
{
this._a = a;
this._b = b;
}
}
public class Compere //主持人
{
public void EventHandler(object sender,MyEventArgs e)//事件处理函数
{
Console.WriteLine("a+b={0}",e._a+e._b);
}
public static void Main()
{
EventCal ec = new EventCal();
Compere c = new Compere();
MyEventArgs e = new MyEventArgs(1, 1); //构造函数传参
ec.OnComputer += new Computer(c.EventHandler);//注册
ec.FireEvent(e);
Console.Read();
}
}
}
这个是有参数的事件。