C# 如何實(shí)現(xiàn)一個(gè)帶通知的List<T>
背景
在很多場景下面我們需要在集合發(fā)生變化的時(shí)候能夠通過一個(gè)事件對外進(jìn)行通知,默認(rèn)的List<T>并沒有此類功能,所以對于這一類需求的業(yè)務(wù)場景下我們需要自己進(jìn)行相關(guān)的擴(kuò)展,這樣才能夠符合我們這一需求,這里我來列舉一個(gè)在項(xiàng)目中經(jīng)常用到的一個(gè)擴(kuò)展類,在后面我們會對這個(gè)進(jìn)行具體的分析和使用到的C#知識點(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>的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
WPF實(shí)現(xiàn)好看的Loading動畫的示例代碼
這篇文章主要介紹了如何利用WPF實(shí)現(xiàn)好看的Loading動畫效果,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定幫助,需要的可以參考一下2022-08-08
C#使用OpenCvSharp4實(shí)現(xiàn)讀取本地視頻
OpenCvSharp4庫是一個(gè)基于.Net封裝的OpenCV庫,這篇文章主要介紹了C#使用OpenCvSharp4實(shí)現(xiàn)讀取本地視頻的詳細(xì)教程,有需要的小伙伴可以參考下2024-01-01
Unity實(shí)現(xiàn)倒計(jì)時(shí)組件
這篇文章主要介紹了Unity實(shí)現(xiàn)倒計(jì)時(shí)組件的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05
C#將Word轉(zhuǎn)換成PDF方法匯總(基于Office和WPS)
這篇文章主要匯總了C#將Word轉(zhuǎn)換成PDF方法,基于Office和WPS的兩種解決方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05
Datagridview使用技巧(9)Datagridview的右鍵菜單
這篇文章主要為大家詳細(xì)介紹了Datagridview使用技巧,Datagridview的右鍵菜單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05
C#實(shí)現(xiàn)窗體中動態(tài)按鈕的設(shè)計(jì)方法
在窗體界面中,通常以按鈕來代替菜單欄的功能,這種形式雖然給用戶一種直觀、界面風(fēng)格各異的感覺,但通常按鈕都是以靜止的形式顯示,所以本文給大家介紹了C#實(shí)現(xiàn)窗體中動態(tài)按鈕的設(shè)計(jì)方法,感興趣的朋友可以參考下2024-04-04

