C#实现带事件处理的Collection

时间:2021-12-27 05:09:50

我们在进行集合处理时,有时希望能够监视集合的变化,并在满足一定条件时触发处理事件。.net框架下似乎(没见到)没有这样的支持,因此有必要我们自己对Collection进行扩展,以下这个简单的C#控制台应用程序便给出一个简单的方案。

1. 核心实现部分代码

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace CollectionWithEvent
{
    public enum CollectionOperation
    {
        Insert,
        Remove,
        Set
    }

    public class CollectionEventArgs<U> : EventArgs
    {
        public CollectionOperation Operation { get; private set; }
        public int Index { get; private set; }
        public U Item { get; private set; }

        public CollectionEventArgs(U item, CollectionOperation operation, int index)
        {
            Item = item;
            Index = index;
            Operation = operation;
        }
    }

    public class CollectionWithEvents<T> : Collection<T>
    {
       
        public event EventHandler<CollectionEventArgs<T>> CollectionChanged;

        public CollectionWithEvents()
        {
        }

        public CollectionWithEvents(IEnumerable<T> items)
            : base(items.ToList())
        {
        }

        protected override void InsertItem(int index, T item)
        {
            base.InsertItem(index, item);
            OnCollectionChanged(item, CollectionOperation.Insert, index);
        }

        protected override void RemoveItem(int index)
        {
            base.RemoveItem(index);
            OnCollectionChanged(default(T), CollectionOperation.Remove, index);
        }

        protected override void SetItem(int index, T item)
        {
            base.SetItem(index, item);
            OnCollectionChanged(item, CollectionOperation.Set, index);
        }

        private void OnCollectionChanged(T item, CollectionOperation operation, int index)
        {
            if(CollectionChanged != null)
                CollectionChanged(this,new CollectionEventArgs<T>(item,operation,index));
                
        }

        public void AddRange(IEnumerable<T> items)
        {
            foreach(var item in items)
                Add(item);
        }
    }
}

2. 测试对象类定义

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

namespace CollectionWithEvent
{
    public class StringObj
    {
        private string _val;
        public string Val
        {
            get
            {
                return _val ?? "";
            }
        }

        public StringObj(string val)
        {
            _val = val;
        }
    }
}

3. 测试主程序

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

namespace CollectionWithEvent
{
    class Program
    {
        static void Main(string[] args)
        {
            CollectionWithEvents<StringObj> col = new CollectionWithEvents<StringObj>();
            col.CollectionChanged += new EventHandler<CollectionEventArgs<StringObj>>(EventChanged);

            col.Insert(0, new StringObj("ni"));
            col.Insert(1, new StringObj("hao"));
            col.Add(new StringObj("ya"));
            col.Add(new StringObj("!"));
            col.RemoveAt(3);
            col[2] = new StringObj("ma");

            Console.ReadKey();
        }

        private static void EventChanged(object sender, CollectionEventArgs<StringObj> e)
        {
            string msg = string.Empty;

            msg = e.Operation.ToString();
            msg += " ";
            msg += e.Index.ToString();
            msg += " ";

            if (e.Item != null)
                msg += e.Item.Val;

            Console.WriteLine(msg);
        }
    }
}

当进行集合操作时会触发绑定的事件,这里的运行结果如下:

C#实现带事件处理的Collection