Spargine is a collection of open-source assemblies and NuGet packages designed for .NET 10, which I have been developing and maintaining since the release of .NET Framework 2. These assemblies are not only a core part of my projects but are also actively deployed in production environments across several companies I collaborate with.
Get Spargine
You can access the source code and NuGet packages here:
- GitHub: Spargine 10
- NuGet: dotNetDaveNuGet
Modern .NET applications—especially those built using MVVM patterns in WPF, MAUI, or Xamarin—often require collections that can notify the UI or business logic when their contents change. While .NET provides ObservableCollection<T> for this purpose, Spargine raises the bar with a more capable and flexible alternative: ObservableList<T> found in the DotNetTips.Spargine.Core assembly and NuGet package.
ObservableList<T> behaves much like a standard List<T>, but with built-in notifications whenever items are added, removed, replaced, or modified. This makes it an excellent choice for applications where collections and dependent components must stay in sync automatically and efficiently.
What Is ObservableList<T>?
ObservableList<T> is a collection designed to combine the familiarity of List<T> with powerful change-tracking capabilities. It provides:
- Collection change notifications whenever items are added, removed, or replaced
- Property change and property changing notifications for fine-grained update control
- Built-in support for custom equality comparers to control how items are compared
The result is a reactive, responsive, and maintainable collection type that integrates cleanly into modern .NET application architectures.
Constructors
ObservableList<T> offers multiple initialization options to suit different scenarios:
- ObservableList()
Creates a new instance using the default equality comparer. - ObservableList(IEqualityComparer<T> comparer)
Creates a new instance with a specified equality comparer. - ObservableList(IEnumerable<T> collection)
Creates a new instance with elements copied from the given collection. - ObservableList(IEnumerable<T> collection, IEqualityComparer<T> comparer)
Creates a new instance with copied elements and a specified equality comparer.
Properties
The collection exposes familiar and useful properties:
- virtual Comparer
Returns the IEqualityComparer<T> object that is used to determine equality for the values in the set. - virtual Count
Gets the number of elements in the collection. - virtual IsReadOnly
Indicates whether the collection is read-only.
Methods
ObservableList<T> includes a rich set of methods that go far beyond basic list operations:
- protected virtual OnCollectionChanged(NotifyCollectionChangedEventArgs e)
Raises the CollectionChanged event. - protected virtual OnPropertyChanged(PropertyChangedEventArgs e)
Raises the PropertyChanged event. - protected virtual OnPropertyChanging(PropertyChangingEventArgs e)
Raises the PropertyChanging event. - virtual Add(T item)
Adds the specified element to the collection if the element already does not exist. - virtual AddRange(IEnumerable<T> items)
Adds a range of items to the collection with optimized notifications. - virtual Clear()
Removes all elements from the collection. - virtual Contains(T item)
Checks if the collection contains a given item. - virtual CopyTo(T[] array) / virtual CopyTo(T[] array, int index)
Copies elements to an array. - virtual EnsureCapacity(int capacity)
Ensures that the underlying hash set can hold the specified number of elements without growing. - virtual ExceptWith(IEnumerable<T> other)
Removes all elements in the specified collection from the current set. - virtual FindAll(Predicate<T> match)
Finds all elements that match the specified predicate. - virtual FirstOrDefault()
Returns the first element, or default(T) if the collection is empty. - virtual IntersectWith(IEnumerable<T> other)
Modifies the current collection to contain only elements that are also present in the specified collection. - virtual IsProperSubsetOf(IEnumerable<T> other)
Determines whether the current collection is a proper subset of the specified collection. - virtual IsSubsetOf(IEnumerable<T> other)
Determines whether the collection is a subset of the specified collection. - virtual IsSuperSetOf(IEnumerable<T> other)
Determines whether the collection is a superset of the specified collection. - virtual LastOrDefault()
Returns the last element, or default(T) if the collection is empty. - virtual Overlaps(IEnumerable<T> other)
Determines whether the current collection overlaps with the specified collection. - virtual Remove(T item)
Removes a specific item. - virtual RemoveRange(IEnumerable<T> items)
Removes a range of items from the collection with optimized notifications. - virtual RemoveWhere(Predicate<T> match)
Removes all elements that match the conditions defined by the specified predicate. - virtual Reset(IEnumerable<T> items)
Replaces all elements with the elements from the specified collection, raising a single Reset notification. - virtual SetEquals(IEnumerable<T> other)
Determines whether the current collection contains the same elements as the specified collection. - virtual SymmetricExceptWith(IEnumerable<T> other)
Modifies the current collection to contain only elements that are present either in it or in the specified collection, but not both. - virtual ToArray()
Converts the ObservableList to an array. - virtual ToList()
Converts the ObservableList to a List<T>. - virtual TrimExcess()
Forces the collection to reduce its capacity to match its current count, minimizing memory overhead. - virtual TryGetValue(T equalValue, out T actualValue)
Searches the set for a given value and returns the equal value it finds, if any. - virtual UnionWith(IEnumerable<T> other)
Modifies the current collection to contain all elements that are present in the ObservableList itself, the specified collection, or both.
Events
To keep your UI and logic synchronized, ObservableList<T> raises the following events:
- NotifyCollectionChangedEventHandler? CollectionChanged
Triggered when the collection’s contents change. - PropertyChangedEventHandler? PropertyChanged
Triggered when a property value changes. - PropertyChangingEventHandler? PropertyChanging;
Triggered just before a property value changes.
These events make ObservableList<T> a natural fit for data-binding scenarios and reactive workflows.
Summary
If your application needs to react automatically to collection changes, ObservableList<T> in Spargine delivers a more flexible and feature-rich alternative to ObservableCollection<T>. With support for bulk operations, set-based logic, custom equality comparisons, and optimized notifications, it’s an excellent choice for UI-heavy applications and real-time data synchronization scenarios.
In short, ObservableList<T> helps you build .NET applications that are responsive, maintainable, and ready for the future.
Get Involved!
The success of open-source projects like Spargine relies on community contributions. If you find these updates useful or have ideas for further improvements, I encourage you to contribute by:
- Submitting pull requests
- Reporting issues
- Suggesting new features
Your input is invaluable in making Spargine an even more powerful tool for the .NET community.
If you are interested in contributing or have any questions, feel free to contact me via email at dotnetdave@live.com. Your support and collaboration are greatly appreciated!
Thank you, and happy coding!
Pick up any books by David McCarter by going to Amazon.com: http://bit.ly/RockYourCodeBooks
Make a one-time donation
Make a monthly donation
Make a yearly donation
Choose an amount
Or enter a custom amount
Your contribution is appreciated.
Your contribution is appreciated.
Your contribution is appreciated.
DonateDonate monthlyDonate yearlyIf you liked this article, please buy David a cup of Coffee by going here: https://www.buymeacoffee.com/dotnetdave
© The information in this article is copywritten and cannot be preproduced in any way without express permission from David McCarter.
Discover more from dotNetTips.com
Subscribe to get the latest posts sent to your email.

