< Summary

Information
Class: SwiftCollections.Observable.SwiftObservableList<T>
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Observable/SwiftObservableList.cs
Line coverage
100%
Covered lines: 64
Uncovered lines: 0
Coverable lines: 64
Total lines: 245
Line coverage: 100%
Branch coverage
100%
Covered branches: 16
Total branches: 16
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%
.ctor(...)100%11100%
.ctor(...)100%11100%
get_Item(...)100%11100%
set_Item(...)100%22100%
Add(...)100%11100%
AddRange(...)100%22100%
AddRange(...)100%11100%
AddRange(...)100%22100%
Remove(...)100%22100%
RemoveAt(...)100%11100%
RemoveAll(...)100%22100%
Insert(...)100%11100%
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/SwiftObservableList.cs

#LineLine coverage
 1using Chronicler;
 2using MemoryPack;
 3using System;
 4using System.Collections.Generic;
 5using System.Collections.Specialized;
 6using System.ComponentModel;
 7using System.Text.Json.Serialization;
 8
 9namespace SwiftCollections.Observable;
 10
 11/// <summary>
 12/// Represents an observable extension of the high-performance <see cref="SwiftList{T}"/>.
 13/// Notifies listeners of changes to its items and structure for reactive programming scenarios.
 14/// </summary>
 15/// <typeparam name="T">The type of elements in the list.</typeparam>
 16[Serializable]
 17[JsonConverter(typeof(StateJsonConverterFactory))]
 18[MemoryPackable]
 19public partial class SwiftObservableList<T> : SwiftList<T>, IStateBacked<SwiftArrayState<T>>, INotifyPropertyChanged, IN
 20{
 21    #region Events
 22
 23    /// <summary>
 24    /// Raised when a property on the list changes.
 25    /// </summary>
 26    public event PropertyChangedEventHandler? PropertyChanged;
 27
 28    /// <summary>
 29    /// Raised when the list's collection is modified.
 30    /// </summary>
 31    public event NotifyCollectionChangedEventHandler? CollectionChanged;
 32
 33    #endregion
 34
 35    #region Constructors
 36
 37    /// <summary>
 38    /// Initializes a new instance of the <see cref="SwiftObservableList{T}"/> class.
 39    /// </summary>
 6440    public SwiftObservableList() : base() { }
 41
 42    /// <summary>
 43    /// Initializes a new instance of the <see cref="SwiftObservableList{T}"/> class with the specified initial capacity
 44    /// </summary>
 245    public SwiftObservableList(int capacity) : base(capacity) { }
 46
 47    /// <summary>
 48    /// Initializes a new instance of the <see cref="SwiftObservableList{T}"/> class that contains elements copied from 
 49    /// </summary>
 1250    public SwiftObservableList(IEnumerable<T> collection) : base(collection) { }
 51
 52    ///  <summary>
 53    ///  Initializes a new instance of the <see cref="SwiftObservableList{T}"/> class with the specified <see cref="Swif
 54    ///  </summary>
 55    ///  <param name="state">The state containing the internal array, count, offset, and version for initialization.</pa
 56    [MemoryPackConstructor]
 1257    public SwiftObservableList(SwiftArrayState<T> state) : base(state) { }
 58
 59    #endregion
 60
 61    #region Properties
 62
 63    /// <summary>
 64    /// Sets or gets the element at the specified index.
 65    /// Raises collection change notifications on modification.
 66    /// </summary>
 67    [JsonIgnore]
 68    [MemoryPackIgnore]
 69    public new T this[int index]
 70    {
 50671        get => base[index];
 72        set
 73        {
 150674            T oldValue = base[index];
 150475            if (!Equals(oldValue, value))
 76            {
 150177                base[index] = value;
 150178                OnCollectionChanged(NotifyCollectionChangedAction.Replace, oldValue, value, index);
 150179                OnPropertyChanged("InnerArray[]");
 80            }
 150481        }
 82    }
 83
 84    #endregion
 85
 86    #region Methods
 87
 88    /// <summary>
 89    /// Adds an element to the end of the list.
 90    /// Raises collection and property change notifications.
 91    /// </summary>
 92    public override void Add(T item)
 93    {
 1105194        base.Add(item);
 1105195        OnCollectionChanged(NotifyCollectionChangedAction.Add, item, _count - 1);
 1105196        OnPropertyChanged(nameof(Count));
 1105197    }
 98
 99    /// <summary>
 100    /// Adds the elements of the specified collection to the end of the current collection.
 101    /// </summary>
 102    /// <param name="items">The collection whose elements should be added to the end of the collection. Cannot be null.<
 103    public override void AddRange(IEnumerable<T> items)
 104    {
 1105        SwiftThrowHelper.ThrowIfNull(items, nameof(items));
 106
 8107        foreach (T item in items)
 3108            Add(item);
 1109    }
 110
 111    /// <summary>
 112    /// Adds the elements of the specified array to the end of the list.
 113    /// Raises collection and property change notifications for each added item.
 114    /// </summary>
 115    public override void AddRange(T[] items)
 116    {
 2117        SwiftThrowHelper.ThrowIfNull(items, nameof(items));
 1118        AddRange(items.AsSpan());
 1119    }
 120
 121    /// <summary>
 122    /// Adds the elements of the specified span to the end of the list.
 123    /// Raises collection and property change notifications for each added item.
 124    /// </summary>
 125    public override void AddRange(ReadOnlySpan<T> items)
 126    {
 16127        for (int i = 0; i < items.Length; i++)
 6128            Add(items[i]);
 2129    }
 130
 131    /// <summary>
 132    /// Removes the first occurrence of a specific object from the list.
 133    /// Raises collection and property change notifications.
 134    /// </summary>
 135    public override bool Remove(T item)
 136    {
 503137        int index = IndexOf(item);
 503138        if (index >= 0)
 139        {
 502140            var removedItem = this[index];
 502141            base.RemoveAt(index);
 502142            OnCollectionChanged(NotifyCollectionChangedAction.Remove, removedItem, index);
 502143            OnPropertyChanged(nameof(Count));
 502144            return true;
 145        }
 146
 1147        return false;
 148    }
 149
 150    /// <summary>
 151    /// Removes the element at the specified index.
 152    /// Raises collection and property change notifications.
 153    /// </summary>
 154    public override void RemoveAt(int index)
 155    {
 3156        var removedItem = this[index];
 1157        base.RemoveAt(index);
 1158        OnCollectionChanged(NotifyCollectionChangedAction.Remove, removedItem, index);
 1159        OnPropertyChanged(nameof(Count));
 1160    }
 161
 162    /// <summary>
 163    /// Removes all elements from the collection that match the conditions defined by the specified predicate.
 164    /// </summary>
 165    /// <remarks>
 166    /// Raises a collection changed event with the Reset action and notifies property changes if any elements are remove
 167    /// This method is useful when you need to remove multiple items based on a condition and notify observers of the ch
 168    /// </remarks>
 169    /// <param name="match">The delegate that defines the conditions of the elements to remove. Cannot be null.</param>
 170    /// <returns>The number of elements removed from the collection.</returns>
 171    public override int RemoveAll(Predicate<T> match)
 172    {
 6173        int removedCount = base.RemoveAll(match);
 174
 5175        if (removedCount > 0)
 176        {
 3177            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
 3178            OnPropertyChanged(nameof(Count));
 179        }
 180
 5181        return removedCount;
 182    }
 183
 184    /// <summary>
 185    /// Inserts an element into the list at the specified index.
 186    /// Raises collection and property change notifications.
 187    /// </summary>
 188    public override void Insert(int index, T item)
 189    {
 1190        base.Insert(index, item);
 1191        OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index);
 1192        OnPropertyChanged(nameof(Count));
 1193    }
 194
 195    /// <summary>
 196    /// Clears all elements from the list.
 197    /// Raises a reset collection change notification.
 198    /// </summary>
 199    public override void Clear()
 200    {
 1201        if (_count > 0)
 202        {
 1203            base.Clear();
 1204            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
 1205            OnPropertyChanged(nameof(Count));
 206        }
 1207    }
 208
 209    #endregion
 210
 211    #region Notifications
 212
 213    /// <summary>
 214    /// Raises the <see cref="PropertyChanged"/> event.
 215    /// </summary>
 216    /// <param name="propertyName">The name of the property that changed.</param>
 217    protected virtual void OnPropertyChanged(string propertyName)
 218    {
 13060219        var handler = PropertyChanged;
 13060220        handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 11221    }
 222
 223    /// <summary>
 224    /// Raises the <see cref="CollectionChanged"/> event for the specified action and items.
 225    /// </summary>
 226    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
 227    {
 13060228        var handler = CollectionChanged;
 13060229        handler?.Invoke(this, args);
 10020230    }
 231
 232    private void OnCollectionChanged(NotifyCollectionChangedAction action, T item, int index)
 233    {
 11555234        var args = new NotifyCollectionChangedEventArgs(action, item, index);
 11555235        OnCollectionChanged(args);
 11555236    }
 237
 238    private void OnCollectionChanged(NotifyCollectionChangedAction action, T oldItem, T newItem, int index)
 239    {
 1501240        var args = new NotifyCollectionChangedEventArgs(action, newItem, oldItem, index);
 1501241        OnCollectionChanged(args);
 1501242    }
 243
 244    #endregion
 245}