C# 如何实现一个带通知的List<T>
作者:Hello——寻梦者! 发布时间:2022-08-05 03:40:26
标签:c#,List
背景
在很多场景下面我们需要在集合发生变化的时候能够通过一个事件对外进行通知,默认的List<T>并没有此类功能,所以对于这一类需求的业务场景下我们需要自己进行相关的扩展,这样才能够符合我们这一需求,这里我来列举一个在项目中经常用到的一个扩展类,在后面我们会对这个进行具体的分析和使用到的C#知识点进行关注。
实现
这里贴出具体的代码实现
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);
}
}
}
注意事项
1 基类中Add这些方法都是非虚方法,这里不能使用重载,所以在自己实现的每一个方法中需要使用 new 关键字进行覆盖。
2 在具体使用的时候需要订阅ItemsChanged事件。
来源:https://www.cnblogs.com/seekdream/p/14453536.html


猜你喜欢
- 开篇Druid号称是Java语言中最好的数据库连接池,并且能够提供强大的监控和扩展功能。作为日常使用较多的数据库连接组件,纯粹个人兴趣研究下
- 一、内存池基础知识1、什么是内存池1.1 池化技术池化技术是计算机中的一种设计模式,主要是指:将程序中经常要使用的计算机资源预先申请出来,由
- 一、Stream流介绍在JDK8时,JAVA新增了lambda表达式,它与 java.io 包里的 InputStream和 OutputS
- Android标题栏最右边添加按钮的实例step1:重写activity的onCreateOptionsMenu方法@Override pu
- 本文实例讲述了Android模拟器实现手机添加文件到sd卡的方法。分享给大家供大家参考,具体如下:在DDMS中直接添加文件到模拟器sd卡如果
- 使用Myeclipse搭建maven项目准备工作安装maven官网下载安装(http://maven.apache.org/)配置环境变量配
- 前言单元测试是编写测试代码,用来检测特定的、明确的、细颗粒的功能。单元测试并不一定保证程序功能是正确的,更不保证整体业务是准备的。单元测试不
- 实践过程效果代码public partial class Form1 : Form{ public Form1()
- vue3新增effectScope相关的API其官方的描述是创建一个 effect 作用域,可以捕获其中所创建的响应式副作用 (即计算属性和
- 最新的IDEA激活方式使用网上传统的那种输入网址的方式激活不了,使用http://idea.lanyus.com/这个网站提供的工具进行1、
- map此内容是方便博主自己记忆内容,不用于公开学习资料,若发现语法错误,自行更正,勿喷map转JSON字符串package com.hanf
- 本文实例讲述了Java删除二叉搜索树最大元素和最小元素的方法。分享给大家供大家参考,具体如下:在前面一篇《Java二叉搜索树遍历操作》中完成
- 本文实例讲述了Android使用Eclipse 打开时“发现了以元素'd:skin'”开头的无效内容。此处不应含有子元素的解
- 前言Kotlin一个强大之处就在于它的扩展函数,巧妙的运用这些扩展函数可以让你写出的代码更加优雅,阅读起来更加流畅,下面总结了在开发中经常用
- 一、Android 个人手机通讯录开发数据存储:SQLite 数据库开发工具:Android Studio二、Phone Module 简介
- 前言继上次skywalking出故障《解析Arthas协助排查线上skywalking不可用问题》不到一个月,线上skywalking又出毛
- Java与Oracle实现事务(JDBC事务)实例详解J2EE支持JDBC事务、JTA事务和容器事务事务,这里说一下怎样实现JDBC事务。&
- 这篇文章主要介绍了Java TreeSet类的简单理解和使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需
- 汉诺塔的规则是:一共三根柱子,一根柱子从上到
- spring配置不扫描service层原因我将contoller给springmvc进行扫描,然后其余所有交给spring扫描然后发现ser