< Summary

Information
Class: SwiftCollections.Observable.SwiftObservableDictionary<T1, T2>
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Observable/SwiftObservableDictionary.cs
Line coverage
100%
Covered lines: 39
Uncovered lines: 0
Coverable lines: 39
Total lines: 169
Line coverage: 100%
Branch coverage
83%
Covered branches: 10
Total branches: 12
Branch coverage: 83.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
.ctor(...)100%11100%
get_Item(...)100%11100%
set_Item(...)75%44100%
Add(...)100%11100%
Remove(...)100%22100%
Clear()50%22100%
OnPropertyChanged(...)100%22100%
OnCollectionChanged(...)100%22100%
OnCollectionChanged(...)100%11100%
OnCollectionChanged(...)100%11100%

File(s)

/home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Observable/SwiftObservableDictionary.cs

#LineLine coverage
 1//=======================================================================
 2// SwiftObservableDictionary.cs
 3//=======================================================================
 4// MIT License, Copyright (c) 2024–present David Oravsky (mrdav30)
 5// See LICENSE file in the project root for full license information.
 6//=======================================================================
 7
 8using Chronicler;
 9using MemoryPack;
 10using System;
 11using System.Collections.Generic;
 12using System.Collections.Specialized;
 13using System.ComponentModel;
 14using System.Text.Json.Serialization;
 15
 16namespace SwiftCollections.Observable;
 17
 18/// <summary>
 19/// Represents a dictionary that notifies listeners of changes to its items and structure.
 20/// </summary>
 21/// <typeparam name="TKey">The type of keys in the dictionary.</typeparam>
 22/// <typeparam name="TValue">The type of values in the dictionary.</typeparam>
 23[Serializable]
 24[JsonConverter(typeof(StateJsonConverterFactory))]
 25[MemoryPackable]
 26public partial class SwiftObservableDictionary<TKey, TValue> : SwiftDictionary<TKey, TValue>, IStateBacked<SwiftDictiona
 27    where TKey : notnull
 28{
 29    #region Events
 30
 31    /// <summary>
 32    /// Raised when a property on the dictionary changes.
 33    /// </summary>
 34    public event PropertyChangedEventHandler? PropertyChanged;
 35
 36    /// <summary>
 37    /// Raised when the dictionary's collection is modified.
 38    /// </summary>
 39    public event NotifyCollectionChangedEventHandler? CollectionChanged;
 40
 41    #endregion
 42
 43    #region Constructor
 44
 45    /// <summary>
 46    /// Initializes a new instance of the SwiftObservableDictionary class.
 47    /// </summary>
 3648    public SwiftObservableDictionary() : base() { }
 49
 50    ///  <summary>
 51    ///  Initializes a new instance of the <see cref="SwiftObservableDictionary{TKey, TValue}"/> class with the specifie
 52    ///  </summary>
 53    ///  <param name="state">The state containing the internal array, count, offset, and version for initialization.</pa
 54    [MemoryPackConstructor]
 1055    public SwiftObservableDictionary(SwiftDictionaryState<TKey, TValue> state) : base(state) { }
 56
 57    #endregion
 58
 59    #region Properties
 60
 61    /// <summary>
 62    /// Gets or sets the value associated with the specified key.
 63    /// Raises property and collection change notifications.
 64    /// </summary>
 65    [JsonIgnore]
 66    [MemoryPackIgnore]
 67    public new TValue this[TKey key]
 68    {
 969        get => base[key];
 70        set
 71        {
 572            if (TryGetValue(key, out TValue oldValue))
 73            {
 574                if (!Equals(oldValue, value))
 75                {
 476                    base[key] = value;
 477                    OnCollectionChanged(NotifyCollectionChangedAction.Replace, key, oldValue, value);
 478                    OnPropertyChanged("Entries[]");
 79                }
 80            }
 581        }
 82    }
 83
 84    #endregion
 85
 86    #region Methods
 87
 88    /// <summary>
 89    /// Adds an element with the provided key and value to the dictionary.
 90    /// Raises a collection change notification.
 91    /// </summary>
 92    public override bool Add(TKey key, TValue value)
 93    {
 2094        bool result = base.Add(key, value);
 2095        OnCollectionChanged(NotifyCollectionChangedAction.Add, key, value);
 2096        OnPropertyChanged("Entries[]"); // Notify that the dictionary contents have changed
 2097        return result;
 98    }
 99
 100    /// <summary>
 101    /// Removes the element with the specified key from the dictionary.
 102    /// Raises a collection change notification if the key existed.
 103    /// </summary>
 104    public override bool Remove(TKey key)
 105    {
 4106        if (TryGetValue(key, out TValue value))
 107        {
 3108            base.Remove(key);
 3109            OnCollectionChanged(NotifyCollectionChangedAction.Remove, key, value);
 3110            OnPropertyChanged("Entries[]"); // Notify that the dictionary contents have changed
 3111            return true;
 112        }
 1113        return false;
 114    }
 115
 116    /// <summary>
 117    /// Clears all elements from the dictionary.
 118    /// Raises a reset collection change notification.
 119    /// </summary>
 120    public override void Clear()
 121    {
 1122        if (Count > 0)
 123        {
 1124            base.Clear();
 1125            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
 1126            OnPropertyChanged(nameof(Count));
 127        }
 1128    }
 129
 130    #endregion
 131
 132    #region Notifications
 133
 134    /// <summary>
 135    /// Raises the <see cref="PropertyChanged"/> event.
 136    /// </summary>
 137    /// <param name="propertyName">The name of the property that changed.</param>
 138    protected virtual void OnPropertyChanged(string propertyName)
 139    {
 28140        var handler = PropertyChanged;
 28141        handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 2142    }
 143
 144    /// <summary>
 145    /// Raises the <see cref="CollectionChanged"/> event for the specified action and items.
 146    /// </summary>
 147    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
 148    {
 28149        var handler = CollectionChanged;
 28150        handler?.Invoke(this, args);
 7151    }
 152
 153    private void OnCollectionChanged(NotifyCollectionChangedAction action, TKey key, TValue value)
 154    {
 23155        var entry = new KeyValuePair<TKey, TValue>(key, value);
 23156        var args = new NotifyCollectionChangedEventArgs(action, entry);
 23157        OnCollectionChanged(args);
 23158    }
 159
 160    private void OnCollectionChanged(NotifyCollectionChangedAction action, TKey key, TValue oldValue, TValue newValue)
 161    {
 4162        var oldEntry = new KeyValuePair<TKey, TValue>(key, oldValue);
 4163        var newEntry = new KeyValuePair<TKey, TValue>(key, newValue);
 4164        var args = new NotifyCollectionChangedEventArgs(action, newEntry, oldEntry);
 4165        OnCollectionChanged(args);
 4166    }
 167
 168    #endregion
 169}