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

这篇具有很好参考价值的文章主要介绍了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或Clear
    public 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;
    }
}

使用示例文章来源地址https://www.toymoban.com/news/detail-796056.html

    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();
    }

到了这里,关于C#监听Dictionary、List的写入操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C# Socket通信从入门到精通(16)——单个同步UDP服务器监听多个客户端C#代码实现

    我们在开发UDP通信程序时,有时候我们也需要开发UDP服务器程序,这个服务器只需要和一个客户端实现通信,比如这篇博文C# Socket通信从入门到精通(15)——单个同步UDP服务器监听一个客户端C#代码实现,但是在实际项目中有的时候需要和多个客户端进行通信,这时和一个客

    2024年01月22日
    浏览(64)
  • C# Socket通信从入门到精通(15)——单个同步UDP服务器监听一个客户端C#代码实现

    我们在开发UDP通信程序时,除了开发UDP客户端程序,有时候我们也需要开发UDP服务器程序,这在实际项目中是经常会遇到的,所以说掌握UDP服务器程序的开发是一项必备的技能,尤其在上位机软件开发领域,掌握UDP服务器程序的开发是走向高级工程师的必经之路,也是面试必

    2024年02月03日
    浏览(60)
  • python list列表写入txt文档的多种方法

    方法一 将列表写入txt文件中 如下代码所示 a是一段二维列表,需要把它写入一个txt文件中。 方法二 数据: u = [[\\\'mov\\\', \\\'push\\\', \\\'push\\\', \\\'call\\\', \\\'push\\\', \\\'push\\\', \\\'push\\\', \\\'call\\\'],[\\\'pop\\\', \\\'push\\\', \\\'call\\\', \\\'pop\\\', \\\'retn\\\', \\\'mov\\\', \\\'push\\\', \\\'call\\\', \\\'push\\\'],[\\\'push\\\', \\\'push\\\', \\\'call\\\', \\\'pop\\\', \\\'call\\\', \\\'pop\\\', \\\'retn\\\', \\\'mov\\\', \\\'push\\\'], [\\\'lea\\\',

    2024年02月10日
    浏览(44)
  • C#中Dictionary与ConcurrentDictionary解锁多线程操作安全之道

      在C#中, Dictionary 是一个常见的字典类型,但它不是线程安全的。为了在多线程环境中确保安全的操作,我们可以使用 ConcurrentDictionary ,这是一个专门设计用于多线程场景的线程安全字典。 首先,我们来看一个使用普通的 Dictionary 的例子。在这个例子中,我们创建一个 D

    2024年01月22日
    浏览(43)
  • 服务器报500错误 No primary or single unique constructor found for interface java.util.List

     批量删除日志记录 前端请求 URL:http://localhost:8080/system/log? ids=3,4,5 Method:DELETE 后端接口: 报错:java.lang.IllegalStateException: No primary or single unique constructor found for interface java.util.List 解决方法:添加@RequestParam注解 原因分析:  由于 Spring Boot 默认情况下会尝试使用请求参数的值来创建

    2024年02月07日
    浏览(40)
  • Windows 安装 WSL 提示:WslRegisterDistribution failed with Error: 0x8007019e wsl --list --online 无法解析服务器

    从 Microsoft Store 安装 WSL后,提示 Windows 功能中 未启用 【适用于Linux的Windows子系统】 1、 查看 Microsoft-Windows-Subsystem-Linux (WSL) 状态 管理员运行 PowerShell 或管理员运行 cmd 上述命令任选其一 如果显示 Disabled ,启用 Microsoft-Windows-Subsystem-Linux (WSL) Windows 10 (≥2004) 上启用,管理员

    2024年02月03日
    浏览(46)
  • 【微信小程序】使用 WebSocket 进行订阅操作、连接监听、接收到服务器的消息事件

    在微信小程序中使用 WebSocket 进行订阅操作,可以通过 wx.connectSocket 方法创建 WebSocket 连接,并通过相关事件处理函数进行订阅和数据处理。 以下是一个示例代码,演示了在微信小程序中使用 WebSocket 进行订阅: 在上述代码中,我们首先使用 wx.connectSocket 方法创建 WebSocket 连接

    2024年02月16日
    浏览(62)
  • c# list集合克隆

    在C#中,List集合是一种泛型集合,可以存储任何类型的对象。克隆一个List集合可以通过以下几种方式实现: 使用List的构造函数 使用List的构造函数可以创建一个新的List对象,并将原始List中的元素复制到新List中。例如: 在上面的代码中, list2 是一个新的List对象,它使用

    2024年02月06日
    浏览(41)
  • C# List 详解一

    目录 一、概述 二、构造函数 1.List()   2.List(IEnumerable)     3.List(Int32)     三、属性 1.Capacity     2.Count     3.Item[Int32]     四、方法 1.Add(T)     2.AddRange(IEnumerable)     3.AsReadOnly()     4.BinarySearch(T) C# List 文档(一) 1.Add(T),2.AddRange(IEnumerable),3.AsReadOnly(),4.BinarySearch(

    2024年02月16日
    浏览(43)
  • C# 自定义List

    目录 一、需求 二、List 常用功能 三、自定义List 四、测试 1.Add 2.Clear 3.Contains 4.IndexOf 5.Insert 6.Remove 7.RemoveAt 结束 微软官方的 List 在命名空间 System.Collections.Generic 中,在平时的开发中 List 用的特别多,在用的时候我们基本不会考虑在 List 中内部是怎么写的,于是,我也写了一

    2023年04月24日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包