今天在博客园看到一些委托事件的东西,想想自己也看了挺多的委托事件列子,但项目并没有怎么用得到,在这里就自己写写一点我自己关于简单的委托事件的认识.
1.最简单能想象得到的委托,大概是长这样子的
namespace DelegateDemo
{
//直接暴露在命名空间之下
public delegate void ToSaydelegate(string content);
static class Program
{
private static string content;
public static string Content
{
get { return content; }
set { content = value; }
}
public static void ToCome(ToSaydelegate del)
{
del(content);
}
static void Main(string[] args)
{
//一种写法
ToSaydelegate dele = new ToSaydelegate(sayHello);
dele += sayGoodby;
dele.Invoke("内容\n");
//委托可以作为参数传递
content = "content\n";
ToCome(dele);
}
public static void sayHello(string content)
{
Console.Write("sayHello "+content);
}
public static void sayGoodby(string content)
{
Console.Write("sayGoodby " + content);
}
}
}
在main函数中直接实例化委托对象,将对应签名的方法作为参数传递,多个方法使用+=,-=方法增加或删除.然后委托对象实例直接调用.在ToCome方法中,证明可以将委托作为参数传递.
2.对委托的保护,加入了事件
namespace ExtDelegate
{
public class App
{
//委托不再暴露
public delegate void Sleepdelegate();
//声明事件变量用于访问
public event Sleepdelegate SleepEvent;
public void Going()
{
if(SleepEvent!=null)
{
SleepEvent();
}
}
}
public class dog
{
public void Call()
{
Console.Write("狗叫了");
}
}
public class thief
{
public void Run()
{
Console.Write("小偷跑了");
}
}
public class host
{
public void awake()
{
Console.Write("主人醒了");
}
}
class Program
{
static void Main(string[] args)
{
App app = new App();
app.SleepEvent+=(new dog()).Call;
app.SleepEvent+=(new thief()).Run;
app.SleepEvent+=(new host()).awake;
app.Going();
Console.ReadKey();
}
}
}
在这里使用了无返回值也无参数的简单委托签名.
3.实现一个带参数无返回值的委托签名
namespace MyDelegate
{
public class Heater
{
private int tempNumber;
public int TempNumber
{
get { return tempNumber; }
set { tempNumber = value; }
}
//委托存在于类里面
public delegate void boildelegate(int num);
//委托类型的事件变量
public event boildelegate BoliEvent;
public void BoilWater()
{
for (int i = 80; i <=100; i++)
{
tempNumber = i;
if (BoliEvent != null)
{
BoliEvent(tempNumber);
}
}
}
}
public class Alarm
{
public void OutputInfo(int t)
{
if(t<=90)
{
Console.Write("正在快速加热\n");
}
else if(100>t && t>95)
{
Console.Write("即将停止加热\n");
}
}
}
public static class Message
{
public static void DispalyMessage(int t)
{
if(t==100)
{
Console.Write("已经停止加热\n");
}
}
}
class Program
{
static void Main(string[] args)
{
Heater heater = new Heater();
heater.BoliEvent += (new Alarm()).OutputInfo;
heater.BoliEvent += Message.DispalyMessage;
heater.BoilWater();
Console.ReadKey();
}
}
}
在main()中不能直接访问到委托类了,但暴露了一个事件来代替,照样能使用+=,-=,并且不能将其赋予null值.
4..Net FrameWork的规范写法
namespace Net_Delegate_Event
{
public class Cool
{
//一些可以被访问的数据
public string typeName = "Name";
private int tempNumber;
public int TempNumber
{
get { return tempNumber; }
set { tempNumber = value; }
}
//委托名后加delegate,并且委托签名为void,带两个参数object(引用数据源对象,EventArgs或子类)
public delegate void coolerdelegate(object sender, CoolerEventArgs e);
//将将委托名的delegate去掉剩余部分加上Event
public event coolerdelegate coolerEvent;
//封转关键的被用于访问的数据源变量数据temp
public class CoolerEventArgs : EventArgs
{
public readonly int temp;
public CoolerEventArgs(int t)
{
this.temp = t;
}
}
//子类可以重写
public virtual void onCooled(CoolerEventArgs e)
{
if (coolerEvent != null)
{
coolerEvent(this, e);
}
}
public void toCool()
{
for (int i = 4; i >= 0; i--)
{
tempNumber = i;
CoolerEventArgs e = new CoolerEventArgs(tempNumber);
onCooled(e);
}
}
}
public class Alarm
{
public void ToAlarm(object sender, Net_Delegate_Event.Cool.CoolerEventArgs e)
{
Cool cool = (Cool)sender;
Console.Write("TypeName:"+cool.typeName+"\n温度:"+e.temp+"\n");
}
}
public class ToMessage
{
public void toDisplay(object sender,Cool.CoolerEventArgs e)
{
Cool cool = (Cool)sender;
if(e.temp==0)
{
Console.Write(cool.typeName+"冷却完成\n");
}
}
}
class Program
{
static void Main(string[] args)
{
Cool cool = new Cool();
cool.coolerEvent += (new Alarm()).ToAlarm;
cool.coolerEvent += (new ToMessage()).toDisplay;
cool.toCool();
Console.ReadKey();
}
}
}