委托和事件
c#中的委托类似于c和c++中的函数指针,但它是面向对象的、类型安全的、可靠的受控对象,也就是在运行时能够保证指向一个有效的方法,不用担心无效地址或越界地址。它是存有某个方法的引用的一种引用类型。委托声明决定了可有该委托引用的方法。
委托声明的格式:
delegate<return type><delegate name><parameter list>
委托实例化时必须用new关键字创建。
比如说小明在寝室打游戏,中午饿了,就打电话委托小强回来的时候给带份饭:
public delegate void BringFoodEventHandler();
所以小强这个类就要有一个带饭的方法:
public class XiaoQiang
{
public void BringFood()
{
Console.WriteLine("这么懒,怎么没饿死你");
}
}
小明类将委托实例化
public class XiaoMing
{
public static void Main(string[] args)
{
BringFoodEventHandler myDelegate = new BringFoodEventHandler(XiaoQiang.BringFood);
myDelegate();
Console.ReadKey();
}
}
委托多播:
委托对象可用+运算符进行合并,用-运算符移除组件委托。利用这一性质创建一个委托调用时的调用方法的列表,称为委托的多播。
比如把上面的场景改一下,说小明委托小强带饭时对小强说饭钱20先帮忙垫上,小强说你上次还欠我10块钱呢,小明说那攒20次30块的饭后一起还你
public delegate int BringFoodEventHandler(int n);
public class XiaoQiang
{
private int debt = 10;
public static int BringFoodThisTime(int n)
{
debt += n;
return debt;
}
public static int BringFoodNTimes(int n)
{
debt *= n;
return debt;
}
public static int GetDebt()
{
return debt;
}
}
public class XiaoMing
{
public static void Main(string[] args)
{
BringFoodEventHandler myDelegate = new BringFoodEventHandler(XiaoQiang.BringFoodThisTime);
myDelegate += XiaoQiang.BringFoodNTimes;
myDelegate(20);
Console.WriteLine("二十次后我得还给小强{0}元", XiaoQiang.GetDebt());
}
}
事件:
事件是类在发生其关注的事情时用来通知的一种方式。
事件的本质就是委托链。使用发布-订阅模型。
比如学校官网通知下周末有活动,小强订阅了官网动态,就会收到通知,小明没有订阅就不会收到通知。
public class ScholWebsite
{
public delegate void NotifyEventHandler();
public event NotifyEventHandler NotifyEvent;
public void Notic()
{
if(NotifyEvent != null)
{
NotifyEvent();
}
}
}
public class XiaoQiang
{
public static void Recieve()
{
Console.WriteLine("Got it!");
}
}
public class XiaoMing
{
public static void Recieve()
{
Console.WriteLine("Rogar");
}
}
class Program
{
public void static Main(string[] args)
{
SchoolWebsite sw = new SchoolWebsite();
sw.NotifyEvent += XiaoQiang.Recieve;
sw.Notice();
Console.ReadKey();
//因为只有小强订阅了,所以只会有Got it!被输出,而Rogar没有
}
}