学习然后整理头绪:委托和事件

发布成“文章”,应该只会出现在我的博客里,而不会在首页的“随笔分类”里出现,这样就不会误导比我还菜的人了,虽然我认为本文没有太大的错误。。。

 

对于“委托和事件”,我确实很无奈,很多次尝试拿下它,每次都放弃了。这几天刚好有空,一定要攻克下来!

学习的时候,主要参考了张子阳写的经典:C# 中的委托和事件 以及它的续。

例子就是无数人都写过的那个热水器。

马上就停电了,赶快整理一下头绪,然后等拉电看动漫>.<

刚才写的时候我不能肯定会成功运行,所以就简化了来做,节约时间嘛。

 

 
  
public class Heater
{
public string type = " 高性能的热水器 " ;
public class boiledEventArgs : EventArgs
{
public readonly int _temp;
public boiledEventArgs( int temp)
{
_temp
= temp;
}
}

public delegate void boiledEventHandler( object sender, boiledEventArgs e);
public event boiledEventHandler boiled;

// 该方法是用于调用事件的,也可以不用该方法,直接在BoileWater()中调用事件
public void OnBoiled(boiledEventArgs e)
{
if (boiled != null )
{
boiled(
this ,e);
}
}
public void BoileWater()
{
for ( int i = 0 ; i < 101 ; i ++ )
{
if (i > 94 )
{
boiledEventArgs e
= new boiledEventArgs(i);
OnBoiled(e);
}
}
}
}
// 警告
public class Alert
{
public void MakeAlert( object sender, Heater.boiledEventArgs e)
{
Heater ht
= (Heater)sender;
Console.WriteLine(
" this is alert type:{0} " ,ht.type);
Console.WriteLine(
" this is alert temperature {0} " ,e._temp);
}
}
class Program
{
static void Main( string [] args)
{
Heater he
= new Heater();
Alert al
= new Alert();
he.boiled
+= al.MakeAlert;

he.BoileWater();
Console.Read();
}
}

 

委托和事件该这样写

 

 
  
public delegate void boiledEventHandler( object sender, boiledEventArgs e);
public event boiledEventHandler boiled;

 

 

要注意委托的签名,应该和“显示器”以及“报警器”里的方法一致,在我这里,就是要和Class Alert里的public void MakeAlert(object sender, Heater.boiledEventArgs e)一致。

换句话说,因为在运行的时候,Heater类里的boiled事件要绑定Alert类里的MakeAlert方法,

所以,boiled事件对应的委托即boiledEventHandler,该委托的签名要和MakeAlert()方法一致。

据说有种东西叫“协变逆变”,我不懂,这里也不讨论。。。

 

运行的时候,先绑定“警告”方法到HT的boiled事件,然后执行HT中的主要方法,即“烧水”!

在“烧水”执行的过程中,需要判断:如果水温到达65℃,那么马上执行OnBoiled方法,当然啦,需要将当前温度传递给它。

在这里,温度被封装在了一个类里面,这个类就是“boiledEventArgs : EventArgs”。我觉得啊,这个类里面可以封装更多的东西。这样,就可以一次性传递很多信息了。

 

在OnBoiled方法中,调用了boiled事件,并传递给它(object sender, boiledEventArgs e),这和该事件对应的委托的签名一致。

该sender就是Heater的实例,在这里,就是he;

e就是之前传递给OnBoiled方法的那个e,它是一个类的实例。

boiled事件在获取了足够的参数以后,就查找它到底绑定了那些方法,然后按顺序开始执行那些方法。

 

哦,我补充说明一下,

1,我觉得,肯定是要验证委托的签名是否和方法的一致,虽然不清楚到底什么时候验证,但肯定是要验证的。

2,执行那些绑定的方法之前,肯定是要把有关的数据传递给被执行的方法的吧,例如Alert类的MakeAlert(object sender, Heater.boiledEventArgs e)方法需要两个参数,不传递参数的话怎么能够执行呢,呵呵。

 

当然,在HEATER类的主方法“烧水”里,可以直接调用boiled事件,然后把OnBoiled方法去掉,一样可以成功运行。

只是,正如我看的资料上说的,约定了调用事件的方法要以“On”开头嘛,就像btn1_OnClick一样。另外,OnBoiled和“烧水”分离开,也不错啊,可以不“烧水”而直接调用该方法。

不过,区别是明显的:

由于“烧水”里采用了循环,所以每次温度改变,都会调用OnBoiled方法,最终调用boiled事件绑定的方法,产生一系列的输出。

而直接调用OnBoiled方法的话,最终只能调用一次绑定的方法,产生一次输出。而且还需要自己实例化一个Heater.boiledEventArgs e,并为它赋值。

 

 

快拉电了,等来电了再说吧。

 

转载于:https://www.cnblogs.com/SeraphWU/articles/1731427.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值