面試官:實現一個帶值變更通知能力的Dictionary

有態度的馬甲發表於2021-08-16

如題, 你知道字典KEY對應的Value什麼時候被覆蓋了嗎?今天我們聊這個剛性需求。

前文提要:

資料獲取元件維護了業務方所有(在用)的連線物件,DBA能在後臺無侵入的切換備份庫。

上文中:DBA在為某個配置字串切換新的連線資訊時,SDK利用ClearPool(DBConnection conn)清空與這個連線相關的連線池。

清空的時機: 維護在用連線的字典鍵值發生變更。

今天本文就來實現一個帶值變更通知能力的字典。

程式設計實踐

關鍵字: 變更 通知 字典

using System;
using System.Collections.Generic;
using System.Text;
namespace DAL
{
    public class ValueChangedEventArgs<TK> : EventArgs
    {
        public TK Key { get; set; }
        public ValueChangedEventArgs(TK key)
        {
            Key = key;
        }
    }

    public class DictionaryWapper<TKey, TValue>
    {
        public object  objLock = new object();
       
        private Dictionary<TKey, TValue> _dict;
        public event EventHandler<ValueChangedEventArgs<TKey>> OnValueChanged;
        public DictionaryWapper(Dictionary<TKey, TValue> dict)
        {
            _dict = dict;
        }
        public TValue this[TKey Key]
        {
            get { return _dict[Key]; }
            set
            {
                lock(objLock)
                {
                    try
                    {
                        if (_dict.ContainsKey(Key) && _dict[Key] != null && !_dict[Key].Equals(value))
                        {
                            OnValueChanged(this, new ValueChangedEventArgs<TKey>(Key));
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"檢測值變更或者觸發值變更事件,發生未知異常{ex}");
                    }
                    finally
                    {
                        _dict[Key] = value;
                    }
                }
            }
        }
    }
}

旁白:

  1. 定義值變更事件OnValueChanged 和變更時傳遞的事件引數ValueChangedEventArgs<TKey>
  2. 如何定義值變更,也就是如何判定值型別、引用型別的相等性 #equalhashcode#
  3. DictionaryWapper的表徵實現也得益於C#索引器特性
訂閱值變更事件
var _dictionaryWapper = new DictionaryWapper<string, string>(new Dictionary<string, string> { });
_dictionaryWapper.OnValueChanged += new EventHandler<ValueChangedEventArgs<string>>(OnConfigUsedChanged);

//----

 public static void OnConfigUsedChanged(object sender, ValueChangedEventArgs<string> e)
{
   Console.WriteLine($"字典{e.Key}的值發生變更,請注意...");          
}

最後像正常Dictionary一樣使用DictionaryWapper:

// ---
 _dictionaryWapper[$"{dbConfig}:{connectionConfig.Provider}"] = connection.ConnectionString;

OK,本文實現了一個 帶值變更通知能力的字典,算是一個剛性需求。
溫習了 C# event 索引器的用法。

相關文章