当前位置: 首页 > news >正文

C#监听Dictionary、List的写入操作

前言

在开发中,对于内置值类型和string我们可以通过封装属性在Set中监听写入操作,但是对于DictionaryList等就不能监听到AddRemove等写入操作。
所以一般采取两种方式监听它们的读写操作,一种是封装操作方法,间接进行监听,第二种就是重写AddRemove等方法。下面介绍第二种方法。

实现

下面是重写了Dictionary的示例,List同理。

using System;
using System.Collections.Generic;// 定义一个委托类型,用于处理字典变化的事件
public delegate void DictionaryChangedEventHandler<TKey, TValue>(object sender, DictionaryChangedEventArgs<TKey, TValue> e);// 定义一个事件参数类,用于封装字典变化的信息
public class DictionaryChangedEventArgs<TKey, TValue> : EventArgs
{// 变化的类型,可以是Add, Remove, Update或Clearpublic DictionaryChangedType ChangeType { get; set; }// 变化的键public TKey Key { get; set; }// 变化的值public TValue Value { get; set; }// 构造函数public DictionaryChangedEventArgs(DictionaryChangedType changeType, TKey key, TValue value){ChangeType = changeType;Key = key;Value = value;}
}// 定义一个枚举类型,用于表示字典变化的类型
public enum DictionaryChangedType
{Init,Add,Remove,Update,Clear,
}// 定义一个继承自Dictionary<TKey,TValue>的类,用于触发字典变化的事件
public class ObservableDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{// 定义一个构造函数,用于接受一个IDictionary<TKey, TValue>类型的参数public ObservableDictionary(IDictionary<TKey, TValue> dictionary){base.Clear();foreach (var item in dictionary){base.Add(item.Key, item.Value);}OnDictionaryChanged(new DictionaryChangedEventArgs<TKey, TValue>(DictionaryChangedType.Init, default, default));}public ObservableDictionary(){OnDictionaryChanged(new DictionaryChangedEventArgs<TKey, TValue>(DictionaryChangedType.Init, default, default));}// 定义一个事件,用于通知字典变化public event DictionaryChangedEventHandler<TKey, TValue> DictionaryChanged;// 重写Add方法,用于在添加元素时触发事件public new void Add(TKey key, TValue value){base.Add(key, value);OnDictionaryChanged(new DictionaryChangedEventArgs<TKey, TValue>(DictionaryChangedType.Add, key, value));}// 重写Remove方法,用于在删除元素时触发事件public new bool Remove(TKey key){if (base.TryGetValue(key, out TValue value)){base.Remove(key);OnDictionaryChanged(new DictionaryChangedEventArgs<TKey, TValue>(DictionaryChangedType.Remove, key, value));return true;}return false;}// 重写索引器,用于在更新元素时触发事件public new TValue this[TKey key]{get => base[key];set{if (base.ContainsKey(key)){base[key] = value;OnDictionaryChanged(new DictionaryChangedEventArgs<TKey, TValue>(DictionaryChangedType.Update, key, value));}else{Add(key, value);}}}// 重写Clear方法,用于在清空字典时触发事件public new void Clear(){base.Clear();OnDictionaryChanged(new DictionaryChangedEventArgs<TKey, TValue>(DictionaryChangedType.Clear, default, default));}// 定义一个虚方法,用于触发事件protected virtual void OnDictionaryChanged(DictionaryChangedEventArgs<TKey, TValue> e){DictionaryChanged?.Invoke(this, e);}public void ResetSubscriptions(){DictionaryChanged = null;}
}

使用示例

    public void Test(){// 创建一个ObservableDictionary实例var dict = new ObservableDictionary<string, int>();// 注册事件处理程序,用于输出字典变化的信息dict.DictionaryChanged += (sender, e) =>{Debug.Log($"ChangeType: {e.ChangeType}, Key: {e.Key}, Value: {e.Value}");};// 添加元素dict.Add("a", 1);dict.Add("b", 2);// 删除元素dict.Remove("a");// 更新元素dict["b"] = 3;dict["c"] = 4;Dictionary<string, int> newDic = new Dictionary<string, int>{{ "acd", 120 }};Debug.LogError(((ObservableDictionary<string, int>)newDic).Count);var newDic1 = new ObservableDictionary<string, int>(newDic);Debug.LogError(newDic1.Count);// 清空字典dict.Clear();}

相关文章:

  • windows下如何搭建Yapi环境
  • 深入 Move 生态,探秘铭文热潮背后的思考
  • nestjs中@Injectable()的实现原理
  • 四、字符串与数值
  • ENNOID-BMS从控板分析-基于LTC6813的版本
  • 【OSG案例详细分析与讲解】之九:【形状变形动画】
  • Ensp AR/WLAN设备启动失败问题 错误代码41 解决方案
  • centos7自动清理nohup.out文件、*.log文件
  • 计数排序(Java语言)
  • 服务容错-熔断策略之断路器hystrix-go
  • VMware workstation安装MX-23.1虚拟机并配置网络
  • 2023 年全国职业院校技能大赛(高职组) “云计算应用”赛项赛卷 B部分解析
  • 分类方法之逻辑回归
  • erlang/OTP 平台(学习笔记)(一)
  • Ovtio不同版本下载
  • 《深入 React 技术栈》
  • Android系统模拟器绘制实现概述
  • avalon2.2的VM生成过程
  • gcc介绍及安装
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • Java小白进阶笔记(3)-初级面向对象
  • mysql中InnoDB引擎中页的概念
  • SpingCloudBus整合RabbitMQ
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • 给初学者:JavaScript 中数组操作注意点
  • 面试遇到的一些题
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 前端代码风格自动化系列(二)之Commitlint
  • 实现简单的正则表达式引擎
  • 新书推荐|Windows黑客编程技术详解
  • 用Python写一份独特的元宵节祝福
  • 如何正确理解,内页权重高于首页?
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • # 消息中间件 RocketMQ 高级功能和源码分析(七)
  • #git 撤消对文件的更改
  • #Z2294. 打印树的直径
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (31)对象的克隆
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (十六)Flask之蓝图
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (转)Mysql的优化设置
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .net refrector
  • .Net Web项目创建比较不错的参考文章
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件