C# 如何實(shí)現(xiàn)一個(gè)帶通知的List<T>
背景
在很多場(chǎng)景下面我們需要在集合發(fā)生變化的時(shí)候能夠通過一個(gè)事件對(duì)外進(jìn)行通知,默認(rèn)的List<T>并沒有此類功能,所以對(duì)于這一類需求的業(yè)務(wù)場(chǎng)景下我們需要自己進(jìn)行相關(guān)的擴(kuò)展,這樣才能夠符合我們這一需求,這里我來列舉一個(gè)在項(xiàng)目中經(jīng)常用到的一個(gè)擴(kuò)展類,在后面我們會(huì)對(duì)這個(gè)進(jìn)行具體的分析和使用到的C#知識(shí)點(diǎn)進(jìn)行關(guān)注。
實(shí)現(xiàn)
這里貼出具體的代碼實(shí)現(xiàn)
using System; using System.Collections.Generic; using System.Linq; namespace XXX.XXX.Core.Utils { public class ItemsChangedEventArgs<T> : EventArgs { public IList<T> RemovedItems { get; private set; } public IList<T> AddedItems { get; private set; } public ItemsChangedEventArgs(IList<T> removedItems, IList<T> addItems) { RemovedItems = removedItems; AddedItems = addItems; } } public delegate void ListItemsChangedEventHandler<T>(object sender, ItemsChangedEventArgs<T> args); public class NotifyList<T> : List<T> { public static NotifyList<T> Empty { get { return new NotifyList<T>(); } } public event ListItemsChangedEventHandler<T> ItemsChanged; protected void OnItemsChanged(IList<T> removedItems, IList<T> addedItems) { ListItemsChangedEventHandler<T> temp = ItemsChanged; temp?.Invoke(this, new ItemsChangedEventArgs<T>(removedItems, addedItems)); } public new void Add(T item) { base.Add(item); OnItemsChanged(Empty, new List<T> { item }); } public new void AddRange(IEnumerable<T> collection) { base.AddRange(collection); OnItemsChanged(Empty, collection.ToList()); } public new void Clear() { T[] array = new T[this.Count]; this.CopyTo(array); base.Clear(); OnItemsChanged(array.ToList(), Empty); } public new bool Remove(T item) { bool ret = base.Remove(item); if (ret) OnItemsChanged(new List<T> { item }, Empty); return ret; } public new int RemoveAll(Predicate<T> match) { IList<T> removedItems = FindAll(match); int count = base.RemoveAll(match); if (removedItems.Count != count) { throw new Exception("[NotifyList][RemoveAll][The number of elements found by the predicate does not match the number of elements removed.]"); } OnItemsChanged(removedItems, Empty); return count; } public new void RemoveAt(int index) { T removedItem = this[index]; base.RemoveAt(index); OnItemsChanged(new List<T> { removedItem }, Empty); } public new void RemoveRange(int index, int count) { IEnumerable<T> range = this.Skip(index + 1).Take(count); base.RemoveRange(index, count); OnItemsChanged(range.ToList(), Empty); } } }
注意事項(xiàng)
1 基類中Add這些方法都是非虛方法,這里不能使用重載,所以在自己實(shí)現(xiàn)的每一個(gè)方法中需要使用 new 關(guān)鍵字進(jìn)行覆蓋。
2 在具體使用的時(shí)候需要訂閱ItemsChanged事件。
以上就是C# 如何實(shí)現(xiàn)一個(gè)帶通知的List<T>的詳細(xì)內(nèi)容,更多關(guān)于C# 實(shí)現(xiàn)一個(gè)帶通知的List<T>的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
WPF實(shí)現(xiàn)好看的Loading動(dòng)畫的示例代碼
這篇文章主要介紹了如何利用WPF實(shí)現(xiàn)好看的Loading動(dòng)畫效果,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定幫助,需要的可以參考一下2022-08-08C#使用OpenCvSharp4實(shí)現(xiàn)讀取本地視頻
OpenCvSharp4庫(kù)是一個(gè)基于.Net封裝的OpenCV庫(kù),這篇文章主要介紹了C#使用OpenCvSharp4實(shí)現(xiàn)讀取本地視頻的詳細(xì)教程,有需要的小伙伴可以參考下2024-01-01深入多線程之:雙向信號(hào)與競(jìng)賽的用法分析
本篇文章是對(duì)雙向信號(hào)與競(jìng)賽的用法進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下2013-05-05對(duì)指定的網(wǎng)頁(yè)進(jìn)行截圖的效果 C#版
對(duì)指定的網(wǎng)頁(yè)進(jìn)行截圖的效果 C#版...2007-08-08Unity實(shí)現(xiàn)倒計(jì)時(shí)組件
這篇文章主要介紹了Unity實(shí)現(xiàn)倒計(jì)時(shí)組件的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05C#將Word轉(zhuǎn)換成PDF方法匯總(基于Office和WPS)
這篇文章主要匯總了C#將Word轉(zhuǎn)換成PDF方法,基于Office和WPS的兩種解決方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05Datagridview使用技巧(9)Datagridview的右鍵菜單
這篇文章主要為大家詳細(xì)介紹了Datagridview使用技巧,Datagridview的右鍵菜單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05C#實(shí)現(xiàn)窗體中動(dòng)態(tài)按鈕的設(shè)計(jì)方法
在窗體界面中,通常以按鈕來代替菜單欄的功能,這種形式雖然給用戶一種直觀、界面風(fēng)格各異的感覺,但通常按鈕都是以靜止的形式顯示,所以本文給大家介紹了C#實(shí)現(xiàn)窗體中動(dòng)態(tài)按鈕的設(shè)計(jì)方法,感興趣的朋友可以參考下2024-04-04