• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
flashpast
博客园    首页    新随笔    联系   管理    订阅  订阅

EventsHelper委托触发类

  • 在我们使用事件的时候常常会这样写:
            public event EventHandler ChangedEvent;
        
       private void OnChangedEvent()
            {
               
    if (ChangedEvent != null)
                {
                    ChangedEvent(
    this, EventArgs.Empty);
                }
            }
        
       private void OnChangeEventAsync()
            {
            
       if (ChangedEvent != null)
                {
                    ChangedEvent.BeginInvoke(
    this, EventArgs.Empty, null, null);
                }
            }
  • 判断事件是否有订阅,触发事件等,是经常重复写的部分,其实我们可以把他们封装起来。
  1. 创建一个EventsHelper静态类,首先完成同步操作:创建以下方法:
            // 私有检查参数函数
            private static bool CheckArguments(Delegate del, params object[] args)
            {
            
       if (del == null) { return false; }
            
       if (args.Length > 7)
                {
                
       throw new ArgumentOutOfRangeException("参数过多");
                }
            
       return true;
            }
            // 委托触发函数
        
       private static void Fire(Delegate del, params object[] args)
            {
            
       foreach (var item in del.GetInvocationList())
                {
                
       try
                    {
                        item.DynamicInvoke(args);
                    }
                
       catch { }
                }
            }
            //非类型安全委托触发函数
        
       public static void UnsafeFire(Delegate del, params object[] args)
            {
            
       if (CheckArguments(del, args))
                {
                    Fire(del, args);
                }
            }
  2. 由于UnsafeFire()方法并没有检查参数类型,所以并不能保证类型安全,于是我们创建一些通用的委托,使用这些泛型委托我们可以创建一些通用的事件。因为十分长的参数并不常用,所以我只创建到参数最长7位的泛型委托。
            public delegate void GenericEventHandler();
        
       public delegate void GenericEventHandler<T>(T t);
        
       public delegate void GenericEventHandler<T, U>(T t, U u);
        
       public delegate void GenericEventHandler<T, U, V>(T t, U u, V v);
        
       public delegate void GenericEventHandler<T, U, V, W>(T t, U u, V v, W w);
        
       public delegate void GenericEventHandler<T, U, V, W, X>(T t, U u, V v, W w, X x);
           
    public delegate void GenericEventHandler<T, U, V, W, X, Y>(T t, U u, V v, W w, X x, Y y);
        
       public delegate void GenericEventHandler<T, U, V, W, X, Y, Z>(T t, U u, V v, W w, X x, Y y, Z z);
  3. 创建安全的委托触发函数。
            public static void Fire(EventHandler del, object sender, EventArgs e)
            {
                UnsafeFire(del, sender, e);
            }
            
    public static void Fire<T>(EventHandler<T> del, object sender, T t) where T : EventArgs
            {
                UnsafeFire(del, sender, t);
            }
            
    public static void Fire(GenericEventHandler del)
            {
                UnsafeFire(del, 
    null);
            }
            
    public static void Fire<T>(GenericEventHandler<T> del, T t)
            {
                UnsafeFire(del, t);
            }
            
    public static void Fire<T, U>(GenericEventHandler<T, U> del, T t, U u)
            {
                UnsafeFire(del, t, u);
            }
            
    public static void Fire<T, U, V>(GenericEventHandler<T, U, V> del, T t, U u, V v)
            {
                UnsafeFire(del, t, u, v);
            }
            
    public static void Fire<T, U, V, W>(GenericEventHandler<T, U, V, W> del, T t, U u, V v, W w)
            {
                UnsafeFire(del, t, u, v, w);
            }
            
    public static void Fire<T, U, V, W, X>(GenericEventHandler<T, U, V, W, X> del, T t, U u, V v, W w, X x)
            {
                UnsafeFire(del, t, u, v, w, x);
            }
            
    public static void Fire<T, U, V, W, X, Y>(GenericEventHandler<T, U, V, W, X, Y> del, T t, U u, V v, W w, X x, Y y)
            {
                UnsafeFire(del, t, v, w, x, y);
            }
            
    public static void Fire<T, U, V, W, X, Y, Z>(GenericEventHandler<T, U, V, W, X, Y, Z> del, T t, U u, V v, W w, X x, Y y, Z z)
            {
                UnsafeFire(del, t, u, v, w, x, y, z);
            }
  4. 完成异步操作:创建类型不安全委托函数异步触发方法。
            private static void FireAsync(Delegate del, params object[] args)
            {
                AsyncFire asyncFire 
    = Fire;
                
    foreach (var item in del.GetInvocationList())
                {
                    
    try
                    {
                        asyncFire.BeginInvoke(del, args, 
    null, null);
                    }
                    
    catch { }
                }
            }
            
    delegate void AsyncFire(Delegate del, params object[] args);
            
    public static void UnsafeFireAsync(Delegate del, params object[] args)
            {
                
    if (CheckArguments(del, args))
                {
                    FireAsync(del, args);
                }
            }
  5. 同3,创建类型安全的委托异步触发。
            public static void FireAsync(EventHandler del, object sender, EventArgs e)
            {
                UnsafeFireAsync(del, sender, e);
            }
            
    public static void FireAsync<T>(EventHandler<T> del, object sender, T t) where T : EventArgs
            {
                UnsafeFireAsync(del, sender, t);
            }
            
    public static void FireAsync(GenericEventHandler del)
            {
                UnsafeFireAsync(del, 
    null);
            }
            
    public static void FireAsync<T>(GenericEventHandler<T> del, T t)
            {
                UnsafeFireAsync(del, t);
            }
            
    public static void FireAsync<T, U>(GenericEventHandler<T, U> del, T t, U u)
            {
                UnsafeFireAsync(del, t, u);
            }
            
    public static void FireAsync<T, U, V>(GenericEventHandler<T, U, V> del, T t, U u, V v)
            {
                UnsafeFireAsync(del, t, u, v);
            }
            
    public static void FireAsync<T, U, V, W>(GenericEventHandler<T, U, V, W> del, T t, U u, V v, W w)
            {
                UnsafeFireAsync(del, t, u, v, w);
            }
            
    public static void FireAsync<T, U, V, W, X>(GenericEventHandler<T, U, V, W, X> del, T t, U u, V v, W w, X x)
            {
                UnsafeFireAsync(del, t, u, v, w, x);
            }
            
    public static void FireAsync<T, U, V, W, X, Y>(GenericEventHandler<T, U, V, W, X, Y> del, T t, U u, V v, W w, X x, Y y)
            {
                UnsafeFireAsync(del, t, v, w, x, y);
            }
            
    public static void FireAsync<T, U, V, W, X, Y, Z>(GenericEventHandler<T, U, V, W, X, Y, Z> del, T t, U u, V v, W w, X x, Y y, Z z)
            {
                UnsafeFireAsync(del, t, u, v, w, x, y, z);
            }
  6. 使用EventsHelper
        class Program
        {
            
    public event EventHandler ChangedEvent;
            
    private string m_name;
            
    public string Name
            {
                
    get { return m_name; }
                
    set
                {
                    
    if (value != m_name)
                    {
                        m_name 
    = value;
                       // 编译器会自动推断委托类型
                     
       EventsHelper.Fire(ChangedEvent, null, null);
                    }
                }
            }
            
    static void Main(string[] args)
            {
                Program pro 
    = new Program();
                pro.ChangedEvent 
    += new EventHandler(pro_ChangedEvent);
                pro.Name 
    = "FlashPast";
                Console.ReadLine();
            }
            
    public static void pro_ChangedEvent(object sender, EventArgs e)
            {
                Console.WriteLine(
    "Name 改变");
            }
        }


posted @ 2009-10-21 22:37  flashpast  阅读(637)  评论(2)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3