< 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: 40
Uncovered lines: 0
Coverable lines: 40
Total lines: 174
Line coverage: 100%
Branch coverage
100%
Covered branches: 12
Total branches: 12
Branch coverage: 100%
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(...)100%44100%
Add(...)100%11100%
Remove(...)100%22100%
Clear()100%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 System;
 9using System.Collections.Generic;
 10using System.Collections.Specialized;
 11using System.ComponentModel;
 12using System.Text.Json.Serialization;
 13using Chronicler;
 14using Chronicler.Serialization;
 15using MemoryPack;
 16
 17namespace SwiftCollections.Observable;
 18
 19/// <summary>
 20/// Represents a dictionary that notifies listeners of changes to its items and structure.
 21/// </summary>
 22/// <typeparam name="TKey">The type of keys in the dictionary.</typeparam>
 23/// <typeparam name="TValue">The type of values in the dictionary.</typeparam>
 24[Serializable]
 25[JsonConverter(typeof(StateJsonConverterFactory))]
 26[MemoryPackable]
 27public partial class SwiftObservableDictionary<TKey, TValue> : SwiftDictionary<TKey, TValue>, IStateBacked<SwiftDictiona
 28    where TKey : notnull
 29{
 30    #region Events
 31
 32    /// <summary>
 33    /// Raised when a property on the dictionary changes.
 34    /// </summary>
 35    public event PropertyChangedEventHandler? PropertyChanged;
 36
 37    /// <summary>
 38    /// Raised when the dictionary's collection is modified.
 39    /// </summary>
 40    public event NotifyCollectionChangedEventHandler? CollectionChanged;
 41
 42    #endregion
 43
 44    #region Constructor
 45
 46    /// <summary>
 47    /// Initializes a new instance of the SwiftObservableDictionary class.
 48    /// </summary>
 7849    public SwiftObservableDictionary() : base() { }
 50
 51    ///  <summary>
 52    ///  Initializes a new instance of the <see cref="SwiftObservableDictionary{TKey, TValue}"/> class with the specifie
 53    ///  </summary>
 54    ///  <param name="state">The state containing the internal array, count, offset, and version for initialization.</pa
 55    [MemoryPackConstructor]
 1056    public SwiftObservableDictionary(SwiftDictionaryState<TKey, TValue> state) : base(state) { }
 57
 58    #endregion
 59
 60    #region Properties
 61
 62    /// <summary>
 63    /// Gets or sets the value associated with the specified key.
 64    /// Raises property and collection change notifications.
 65    /// </summary>
 66    [JsonIgnore]
 67    [MemoryPackIgnore]
 68    public new TValue this[TKey key]
 69    {
 1170        get => base[key];
 71        set
 72        {
 573            if (TryGetValue(key, out TValue oldValue))
 74            {
 475                if (!Equals(oldValue, value))
 76                {
 377                    base[key] = value;
 378                    OnCollectionChanged(NotifyCollectionChangedAction.Replace, key, oldValue, value);
 379                    OnPropertyChanged("Entries[]");
 80                }
 81            }
 82            else
 83            {
 184                Add(key, value);
 85            }
 286        }
 87    }
 88
 89    #endregion
 90
 91    #region Methods
 92
 93    /// <summary>
 94    /// Adds an element with the provided key and value to the dictionary.
 95    /// Raises a collection change notification.
 96    /// </summary>
 97    public override bool Add(TKey key, TValue value)
 98    {
 4999        bool result = base.Add(key, value);
 49100        OnCollectionChanged(NotifyCollectionChangedAction.Add, key, value);
 49101        OnPropertyChanged("Entries[]"); // Notify that the dictionary contents have changed
 49102        return result;
 103    }
 104
 105    /// <summary>
 106    /// Removes the element with the specified key from the dictionary.
 107    /// Raises a collection change notification if the key existed.
 108    /// </summary>
 109    public override bool Remove(TKey key)
 110    {
 4111        if (TryGetValue(key, out TValue value))
 112        {
 3113            base.Remove(key);
 3114            OnCollectionChanged(NotifyCollectionChangedAction.Remove, key, value);
 3115            OnPropertyChanged("Entries[]"); // Notify that the dictionary contents have changed
 3116            return true;
 117        }
 1118        return false;
 119    }
 120
 121    /// <summary>
 122    /// Clears all elements from the dictionary.
 123    /// Raises a reset collection change notification.
 124    /// </summary>
 125    public override void Clear()
 126    {
 6127        if (Count > 0)
 128        {
 3129            base.Clear();
 3130            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
 3131            OnPropertyChanged(nameof(Count));
 132        }
 6133    }
 134
 135    #endregion
 136
 137    #region Notifications
 138
 139    /// <summary>
 140    /// Raises the <see cref="PropertyChanged"/> event.
 141    /// </summary>
 142    /// <param name="propertyName">The name of the property that changed.</param>
 143    protected virtual void OnPropertyChanged(string propertyName)
 144    {
 58145        var handler = PropertyChanged;
 58146        handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 4147    }
 148
 149    /// <summary>
 150    /// Raises the <see cref="CollectionChanged"/> event for the specified action and items.
 151    /// </summary>
 152    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
 153    {
 58154        var handler = CollectionChanged;
 58155        handler?.Invoke(this, args);
 9156    }
 157
 158    private void OnCollectionChanged(NotifyCollectionChangedAction action, TKey key, TValue value)
 159    {
 52160        var entry = new KeyValuePair<TKey, TValue>(key, value);
 52161        var args = new NotifyCollectionChangedEventArgs(action, entry);
 52162        OnCollectionChanged(args);
 52163    }
 164
 165    private void OnCollectionChanged(NotifyCollectionChangedAction action, TKey key, TValue oldValue, TValue newValue)
 166    {
 3167        var oldEntry = new KeyValuePair<TKey, TValue>(key, oldValue);
 3168        var newEntry = new KeyValuePair<TKey, TValue>(key, newValue);
 3169        var args = new NotifyCollectionChangedEventArgs(action, newEntry, oldEntry);
 3170        OnCollectionChanged(args);
 3171    }
 172
 173    #endregion
 174}