自己动手用委托模拟.net中的事件机制
原理:委托支持多播委托,即:可以将多个方法绑定到同一个委托变量上(.NET有十分方便的语法实现和解除多播委托:+=和-=),形成所谓的委托链。
在.net开发中,我们之所以能方便地对某个控件增加事件,就是因为.net控件巧妙地封装了委托,这个从其增加事件的代码中可以很清除地看出:
this.button1.Click += new System.EventHandler(this.button1_Click)
private void button1_Click(object sender,EventArgs e){...}
知道了原理,就可以自己模拟出事件机制,代码:
//定义被触发者
public class Caculator
{
public class CaculateEvents : EventArgs
{
public readonly int x, y;
public CaculateEvents(int x, int y)
{
this.x = x;
this.y = y;
}
}
public delegate void CaculateEventHander(object sender, CaculateEvents e);
public event CaculateEventHander myhandler;
protected virtual void onCaculate(CaculateEvents e)
{
if (myhandler != null)
{
myhandler(this, e);
}
}
public void Caculate(int x, int y)
{
CaculateEvents e = new CaculateEvents(x, y);
onCaculate(e);
}
}
//定义呼叫者
class caller
{
public void Add(object sender, Caculator.CaculateEvents e)
{
Console.WriteLine(e.x + e.y);
}
public void Sub(object sender, Caculator.CaculateEvents e)
{
Console.WriteLine(e.x - e.y);
}
}
//模拟事件
class Program
{
static void Main(string[] args)
{
caller mycaler = new caller();
Caculator caculator = new Caculator();
caculator.myhandler += mycaler.Add;
caculator.myhandler += mycaler.Sub;
caculator.Caculate(100, 200);
Console.ReadLine();
}
}
public class Caculator
{
public class CaculateEvents : EventArgs
{
public readonly int x, y;
public CaculateEvents(int x, int y)
{
this.x = x;
this.y = y;
}
}
public delegate void CaculateEventHander(object sender, CaculateEvents e);
public event CaculateEventHander myhandler;
protected virtual void onCaculate(CaculateEvents e)
{
if (myhandler != null)
{
myhandler(this, e);
}
}
public void Caculate(int x, int y)
{
CaculateEvents e = new CaculateEvents(x, y);
onCaculate(e);
}
}
//定义呼叫者
class caller
{
public void Add(object sender, Caculator.CaculateEvents e)
{
Console.WriteLine(e.x + e.y);
}
public void Sub(object sender, Caculator.CaculateEvents e)
{
Console.WriteLine(e.x - e.y);
}
}
//模拟事件
class Program
{
static void Main(string[] args)
{
caller mycaler = new caller();
Caculator caculator = new Caculator();
caculator.myhandler += mycaler.Add;
caculator.myhandler += mycaler.Sub;
caculator.Caculate(100, 200);
Console.ReadLine();
}
}