溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#消息事件封裝

發(fā)布時間:2020-07-09 07:49:17 來源:網(wǎng)絡 閱讀:1912 作者:Aonaufly 欄目:系統(tǒng)運維

本人一直認為AS3的事件處理機制很是給力 , 今天鼓搗了出來并完美得通過了測試。在AS3中使用函數(shù)addEventListener添加事件偵聽,用removeEventListener移除事件偵聽。著用封裝的一個類庫可以徹底地終結(jié)消息傳遞中無規(guī)則,無規(guī)律的混亂狀態(tài),從而達到代碼邏輯清晰性。改起來也相當簡單(做過程序員的都懂)。

關于此類庫的實現(xiàn)原理 , 其實使用的是委托(delegate),讓偵聽函數(shù)(觀察者)掛載到此委托上,當然消息有不同的類型,如windows系統(tǒng)中有單擊,雙擊,右擊等不同的事件類型,在這個類庫里面都有實現(xiàn)。

首先,需要指出:

IEventType     ( 所有事件類型的接口 )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MsgEventLib.com
{
    public interface IEventType
    {
        /// <summary>
        /// 類的類型
        /// </summary>
        Type EventMainType { get; }
        String GetEventTypeName(string type);
    }
}

思想:事件類型以 類的Type.Name + "_" + 事件名稱 。 以GetEventTypeName方法實現(xiàn)。

傳遞的消息體:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MsgEventLib.com
{
    public class BaseEvent
    {
        public BaseEvent(string eventType, object sender, object msg)
        {
            this.eventType = eventType;
            this.sender = sender;
            this.msg = msg;
        }
        private string @eventType;
        public string EventType
        {
            set { this.eventType = value; }
            get { return this.eventType; }
        }
        private object @sender;
        public Object Sender 
        {
            set { this.sender = value; }
            get { return this.sender; }
        }
        private object @msg;
        public object Msg
        {
            set { this.msg = value; }
            get { return this.msg; }
        }
    }
}

其中:eventType為事件類型名稱 GetEventTypeName , Sender為發(fā)送者 , Msg為消息體


事件偵聽管理器的實現(xiàn)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MsgEventLib.com
{
    public sealed class EventListener : IEventListener
    {
        private static IEventListener @instance;
        public static IEventListener Instance
        {
            get {
                if (instance == null) instance = new EventListener();
                return instance;
            }
        }
        private Dictionary<string, DeListener> @listeners;
        private EventListener()
        {
            @listeners = new Dictionary<string, DeListener>();
        }
        public void AddEventListener(string type, DeListener myListener)
        {
            if (!@listeners.ContainsKey(type))
                @listeners.Add(type, myListener);
            else
                @listeners[type] += myListener;
        }
        public void RemoveEventListener(string type, DeListener myListener)
        {
            if (@listeners.ContainsKey(type))
            {
                @listeners[type] -= myListener;
                if (@listeners[type] == null)
                    @listeners.Remove(type);
            }
        }
        public void RemoveAllEventListener()
        {
            if (@listeners != null && @listeners.Count > 0)
            {
                List<string> keys = new List<string>(@listeners.Keys);//獲得所有的鍵值
                for (int j = 0; j < keys.Count; j++)
                {
                    if (@listeners[keys[j]] != null)
                    {
                        Delegate[] des = @listeners[keys[j]].GetInvocationList();
                        if (des != null && des.Length > 0)
                        {
                            for (int i = 0; i < des.Length; i++)
                            {
                                @listeners[keys[j]] -= des[i] as DeListener;
                            }
                        }
                    }
                    @listeners.Remove(keys[j]);
                }
            }
        }
        public DeListener GetDeListenerByType(string type)
        {
            if (@listeners != null && @listeners.ContainsKey(type))
            {
                return @listeners[type];
            }
            return null;
        }
        public void Destory()
        {
            this.RemoveAllEventListener();
            if (@instance != null) @instance = null;
        }
    }
}

值得注意的是 , 字典 : key為事件類型(GetEventTypeName) , value為委托(可能有多個掛載/觀察者)


關于事件發(fā)送者(主題)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MsgEventLib.com
{
    public sealed class EventDispacterManager : IEventDispacterManager
    {
        private static IEventDispacterManager @instance;
        public static IEventDispacterManager Instance
        {
            get
            {
                if (instance == null) instance = new EventDispacterManager();
                return instance;
            }
        }
        public void Dispatch(string type , BaseEvent @myevent)
        {
            DeListener target = EventListener.Instance.GetDeListenerByType(type);
            if (target != null)
            {
                target(@myevent);
            }
        }
    }
}

測試的結(jié)果

1 , 事件類型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MsgEventLib.com;
namespace TestA.com
{
    public class MyEventType : IEventType
    {
        private static MyEventType @instance;
        public static MyEventType Instance
        {
            get {
                if (@instance == null) @instance = new MyEventType();
                return @instance;
            }
        }
        public Type EventMainType
        {
            get { return typeof(MyEventType); }
        }
        public string GetEventTypeName(string type)
        {
            return this.EventMainType.Name + "_" + type;
        }
        public static string CLOSE_WINDOWS = "CLOSE_WINDOWS";
        public static string OTHRT_TYPE = "OTHRT_TYPE";
    }
}

2 , 3個類(偵聽著)

①:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MsgEventLib.com;
namespace TestA.com
{
    public sealed class Listeners
    {
        public Listeners()
        { 
            string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS);
            EventListener.Instance.AddEventListener(type, this.Li);
        }
        private void Li(BaseEvent e)
        {
            Console.WriteLine("Listeners 觸發(fā)了Event {0} ", e.Msg);
        }
    }
}

②:

using MsgEventLib.com;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestA.com
{
    public sealed class Lis2
    {
        public Lis2()
        {
            string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS);
            EventListener.Instance.AddEventListener(type, this.Li);
        }
        private void Li(BaseEvent e)
        {
            Console.WriteLine("Lis2 觸發(fā)了Event {0} ", e.Msg);
        }
        public void RemoveLis()
        { 
            string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS);
            EventListener.Instance.RemoveEventListener(type, this.Li);
            Console.WriteLine("Lis2 移除了事件偵聽!");
        }
    }
}

③:

using MsgEventLib.com;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestA.com
{
    public sealed class Lis3
    {
        public Lis3()
        {
            string type = MyEventType.Instance.GetEventTypeName(MyEventType.OTHRT_TYPE);
            EventListener.Instance.AddEventListener(type, this.Li);
        }
        private void Li(BaseEvent e)
        {
            Console.WriteLine("Lis3 觸發(fā)了Event {0} ", e.Msg);
        }
    }
}

事件發(fā)送者

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MsgEventLib.com;
namespace TestA.com
{
    public sealed class Dispatch
    {
        public void Dis()
        { 
            string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS);
            EventDispacterManager.Instance.Dispatch(type,
                new BaseEvent(type, this, "Event_關閉你的窗口"));
        }
    }
}

測試:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TestA.com;


namespace TestA
{
    public class Program
    {
        static void Main(string[] args)
        {
            Dispatch di = new Dispatch();
            Listeners li = new Listeners();
            Lis2 li2 = new Lis2();
            Lis3 li3 = new Lis3();
            di.Dis();
            li2.RemoveLis();
            di.Dis();

            Console.Read();

        }
    }
}

結(jié)果:

C#消息事件封裝

因為Lis3偵聽的不是事件CLOSE_WINDOWS , 既不會觸發(fā) 。 因為Lis2移除了事件,所以第二次不會觸發(fā)。

這只是部分大碼。詳細請見附件。

附件:http://down.51cto.com/data/2366478
向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI