Unity3d-C#之Delegate和Event疑惑?
来源:互联网 发布:撮合交易 算法 编辑:程序博客网 时间:2024/05/22 00:32
1.如果多次注册同一个事件处理函数时,触发时处理函数是否也会多次触发?
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace TestCSharp{ class Animation { public delegate void PlayHandler(); public event PlayHandler Callback; public Animation() { this.Callback += Move; this.Callback += Move; this.Callback += Move; this.Callback(); } public void Move() { Console.WriteLine("Move"); } public void Run() { Console.WriteLine("Run"); } public void Jump() { Console.WriteLine("Jump"); } }}
可以注册多次同一个函数,触发时会如上图所示执行多次.
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace TestCSharp{ class Animation { public delegate void PlayHandler(); public event PlayHandler Callback; public Animation() { this.Callback += Move; this.Callback -= Move; this.Callback -= Move; this.Callback(); } public void Move() { Console.WriteLine("Move"); } public void Run() { Console.WriteLine("Run"); } public void Jump() { Console.WriteLine("Jump"); } }}
注册一次,可以注销多次,但是要注意触发时要检查是否为空,做如下修改后避免如上图的空指针异常
if (this.Callback != null) { this.Callback(); }
3.如何认定两个事件处理函数是一样的? 如果是匿名函数呢?
using System.Text;namespace TestCSharp{ class Animation { public delegate void PlayHandler(); public event PlayHandler Callback; public Animation() { this.Callback += ()=> Console.WriteLine("Jump"); //Event Unsubscription Via Anonymous Delegate this.Callback -= () => Console.WriteLine("Jump"); } }}
Resharper给出提示Event Unsubscription Via Anonymous Delegate,看起来一致的匿名函数,实际上方法签名是不一样,所以不能如上代码所示取消订阅一个匿名方法。如下代码给出如何取消订阅匿名方法的解决方案。
using System.Text;namespace TestCSharp{ class Animation { public delegate void PlayHandler(); public event PlayHandler Callback; public Animation() { PlayHandler func = () => Console.WriteLine("Jump"); this.Callback += func; this.Callback -= func; this.Callback += func; this.Callback(); } }}
更多取消匿名事件的资料参见官方文档:http://msdn.microsoft.com/en-us/library/ms366768.aspx
4.如果不手动注销事件函数,系统会帮我们回收吗?
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace TestCSharp{ class EventSource { public delegate void PlayHandler(); public event PlayHandler Callback; public void Excute() { if (this.Callback != null) { this.Callback(); } } }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace TestCSharp{ class Listener { public Listener(EventSource source) { source.Callback += Run; } private void Run() { Console.WriteLine("Run"); } ~Listener() { Console.WriteLine("Listener 销毁"); } }}
using System;using System.Collections;using System.Collections.Generic;namespace TestCSharp{ class MainClass { public static void Main(string[] args) { EventSource s = new EventSource(); Listener l = new Listener(s); s.Excute(); l = null; Gc(); s.Excute(); s = null; Gc(); } public static void Gc() { Console.WriteLine("GC 开始"); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); Console.WriteLine("GC 结束"); } } }
注意第二次调用s.Excute()前,已将listener赋为null,并执行Gc,但是仍然输出Run。直到将source赋为null时,listener才被回收掉。
下面我们手工注销事件,看看系统能不能自动回收?
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace TestCSharp{ class Listener { public Listener(EventSource source) { source.Callback += Run; } //添加一个手工注销方法 public void DeregisterEvent(EventSource source) { source.Callback -= Run; } private void Run() { Console.WriteLine("Run"); } ~Listener() { Console.WriteLine("Listener 销毁"); } }}
using System;using System.Collections;using System.Collections.Generic;namespace TestCSharp{ class MainClass { public static void Main(string[] args) { EventSource s = new EventSource(); Listener l = new Listener(s); s.Excute(); //手工调用注销 l.DeregisterEvent(s); l = null; Gc(); s.Excute(); s = null; Gc(); } public static void Gc() { Console.WriteLine("GC 开始"); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); Console.WriteLine("GC 结束"); } } }
这次我们可以看到run执行一次,listener也早早的被回收了。
更多系统回收资料参见:http://www.codeproject.com/Articles/29922/Weak-Events-in-C
0 0
- Unity3d-C#之Delegate和Event疑惑?
- C# delegate和C# event
- C#中的delegate和event
- C#中的delegate和event
- C#中的delegate和event
- C#中的delegate和event
- C#中的delegate和event
- C#中的delegate和event
- C#中的Delegate和Event
- C#中的delegate和event
- C#中的delegate和event
- C#中的delegate和event
- C#中的delegate和event
- C#中的delegate和event
- C#中的delegate和event
- C#中的delegate和event
- C#中的delegate和event
- C#中的delegate和event
- JqueryEasyUI中的Datagrid获取选中行的数据
- Python中的字符串处理
- 谁能代表8寸平板 :皓丽H8平板 VS iPad mini
- IPtables中SNAT和MASQUERADE的区别
- PAT-最大子列和问题
- Unity3d-C#之Delegate和Event疑惑?
- ASP.NET的票据工具类FormsAuthenticationTicket
- Node.js 入门
- 图像处理算法
- C#_WinForm学习
- 发散按钮浅谈
- 动态规划法解0-1背包问题
- OpenCV2实时图像处理在Windows下的优化
- mysql字段类型及占用字节