委托入门-事件与委托

来源:互联网 发布:java培训能找到工作吗 编辑:程序博客网 时间:2024/04/29 19:32


这篇博客是接着上篇博客写得,内容是委托和事件的对比。

还是通过实例来进行说明

普通版



static void Main(string[] args)        {            Cat tom = new Cat();            Mouse sherry = new Mouse("sherry");            Mouse yara = new Mouse("yara");          tom.catMove += new Cat.Move(sherry.mouseMove);            tom.catMove += new Cat.Move(yara.mouseMove);            tom.CatMove();        }    }    public class Cat {        public delegate void Move();        public Move catMove;        public void CatMove() {            Console.WriteLine("猫来了");            catMove();        }    }    public class Mouse    {        private string mouse;        public Mouse(string mouse)        {            this.mouse = mouse;        }        public void mouseMove()        {            Console.WriteLine(mouse + "快跑");        } 




代码分析:
一段非常简单的委托链的代码。实现了一只猫触发了多只老鼠的设定。缺点在于委托变量被公开了。和普通变量不同,委托链中可是存储着大量的方法链条的,如果被不相关类随意改变,其造成的损失可想而知。为了解决安全性的问题,我们通常将变量设置为私有的。但是如果你想这么解决委托的安全问题就会发现失去了delegate的意义。因为无法通过委托给方法指向具体的方法地址了。这个情况下,事件就闪亮登场了。
将上述代码进行修改。

事件版

Mouse tom = new Mouse("TOM");            Mouse jerry = new Mouse("JERRY");            Cat harry = new Cat();            harry.catMove += new Cat.Move(tom.MouseMove);            harry.catMove += new Cat.Move(jerry.MouseMove);            harry.CatMove();                    }    }        class Cat {        public delegate void Move();        public event Move catMove;        public void CatMove(){            Console.WriteLine("猫来了。");            catMove();        }     }    class Mouse {        private string sa;        public Mouse(string sa){            this.sa=sa;        }        public void MouseMove(){           Console.WriteLine(sa+"快跑");        }


可以发现基本没什么变化,只是多了个event而已。

event之下,c#究竟为我们做了什么呢。让我们使用reflector来走近它,最终发现代码被编译成下面这个样子

private Move catMove;public void add_catMove(Move value){    Move move2;    Move catMove = this.catMove;    do    {        move2 = catMove;        Move move3 = (Move) Delegate.Combine(move2, value);        catMove = Interlocked.CompareExchange<Move>(ref this.catMove, move3, move2);    }    while (catMove != move2);}    public void add_catMove(Move value){    Move move2;    Move catMove = this.catMove;    do    {        move2 = catMove;        Move move3 = (Move) Delegate.Combine(move2, value);        catMove = Interlocked.CompareExchange<Move>(ref this.catMove, move3, move2);    }    while (catMove != move2);} public void remove_catMove(Move value){    Move move2;    Move catMove = this.catMove;    do    {        move2 = catMove;        Move move3 = (Move) Delegate.Remove(move2, value);        catMove = Interlocked.CompareExchange<Move>(ref this.catMove, move3, move2);    }    while (catMove != move2);}    public void remove_catMove(Move value){    Move move2;    Move catMove = this.catMove;    do    {        move2 = catMove;        Move move3 = (Move) Delegate.Remove(move2, value);        catMove = Interlocked.CompareExchange<Move>(ref this.catMove, move3, move2);    }    while (catMove != move2);} 



仔细对比我们可以发现cat类中明明是用public修饰的委托居然变成了私有。不仅仅如此。事件拥有了两个属于自己的公共方法,功能对应于+=-=。至此我们可以简单地做个总结:委托不仅将委托变成私有的,还自动拥有了addremove方法,极大地便利了我们的编程。

总结

其实事件也是一种委托。事件是在委托基础上进一步的封装和处理。事件=安全的多播委托




0 0
原创粉丝点击