< 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: 173
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 MemoryPack;
 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>
 3848    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    {
 1169        get => base[key];
 70        set
 71        {
 572            if (TryGetValue(key, out TValue oldValue))
 73            {
 474                if (!Equals(oldValue, value))
 75                {
 376                    base[key] = value;
 377                    OnCollectionChanged(NotifyCollectionChangedAction.Replace, key, oldValue, value);
 378                    OnPropertyChanged("Entries[]");
 79                }
 80            }
 81            else
 82            {
 183                Add(key, value);
 84            }
 285        }
 86    }
 87
 88    #endregion
 89
 90    #region Methods
 91
 92    /// <summary>
 93    /// Adds an element with the provided key and value to the dictionary.
 94    /// Raises a collection change notification.
 95    /// </summary>
 96    public override bool Add(TKey key, TValue value)
 97    {
 2098        bool result = base.Add(key, value);
 2099        OnCollectionChanged(NotifyCollectionChangedAction.Add, key, value);
 20100        OnPropertyChanged("Entries[]"); // Notify that the dictionary contents have changed
 20101        return result;
 102    }
 103
 104    /// <summary>
 105    /// Removes the element with the specified key from the dictionary.
 106    /// Raises a collection change notification if the key existed.
 107    /// </summary>
 108    public override bool Remove(TKey key)
 109    {
 4110        if (TryGetValue(key, out TValue value))
 111        {
 3112            base.Remove(key);
 3113            OnCollectionChanged(NotifyCollectionChangedAction.Remove, key, value);
 3114            OnPropertyChanged("Entries[]"); // Notify that the dictionary contents have changed
 3115            return true;
 116        }
 1117        return false;
 118    }
 119
 120    /// <summary>
 121    /// Clears all elements from the dictionary.
 122    /// Raises a reset collection change notification.
 123    /// </summary>
 124    public override void Clear()
 125    {
 2126        if (Count > 0)
 127        {
 1128            base.Clear();
 1129            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
 1130            OnPropertyChanged(nameof(Count));
 131        }
 2132    }
 133
 134    #endregion
 135
 136    #region Notifications
 137
 138    /// <summary>
 139    /// Raises the <see cref="PropertyChanged"/> event.
 140    /// </summary>
 141    /// <param name="propertyName">The name of the property that changed.</param>
 142    protected virtual void OnPropertyChanged(string propertyName)
 143    {
 27144        var handler = PropertyChanged;
 27145        handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 4146    }
 147
 148    /// <summary>
 149    /// Raises the <see cref="CollectionChanged"/> event for the specified action and items.
 150    /// </summary>
 151    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
 152    {
 27153        var handler = CollectionChanged;
 27154        handler?.Invoke(this, args);
 7155    }
 156
 157    private void OnCollectionChanged(NotifyCollectionChangedAction action, TKey key, TValue value)
 158    {
 23159        var entry = new KeyValuePair<TKey, TValue>(key, value);
 23160        var args = new NotifyCollectionChangedEventArgs(action, entry);
 23161        OnCollectionChanged(args);
 23162    }
 163
 164    private void OnCollectionChanged(NotifyCollectionChangedAction action, TKey key, TValue oldValue, TValue newValue)
 165    {
 3166        var oldEntry = new KeyValuePair<TKey, TValue>(key, oldValue);
 3167        var newEntry = new KeyValuePair<TKey, TValue>(key, newValue);
 3168        var args = new NotifyCollectionChangedEventArgs(action, newEntry, oldEntry);
 3169        OnCollectionChanged(args);
 3170    }
 171
 172    #endregion
 173}