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
Dictionaries are one of the most frequently used data structures in .NET applications—and also one of the easiest places to introduce subtle bugs, unnecessary allocations, and repetitive code. Patterns such as check-then-add, update-or-insert, defensive null checks, and manual conversions to concurrent or immutable forms show up everywhere, cluttering otherwise clean code.
The DictionaryExtensions class in the DotNetTips.Spargine.Extensions project was created to address these issues directly. It provides a carefully designed set of extension methods for IDictionary<TKey, TValue> that improve correctness, reduce boilerplate, and enable modern .NET performance optimizations. These extensions standardize common dictionary operations, encourage safer usage patterns, and make it trivial to transition between mutable, immutable, concurrent, and read-only dictionary types.
This article documents the available methods in DictionaryExtensions and explains how they can simplify your dictionary-heavy code while improving performance and maintainability.
Methods
Below is the complete set of methods currently available in the DictionaryExtensions class.
- AddIfNotExists<TKey, TValue>(TKey key, TValue value)
Adds the specified key and value to the dictionary if the key does not already exist. - AddRange<T, TKey, TValue>(IEnumerable<T> items, Func<T, TKey> keyFunction, Func<T, TValue> valueFunction) where TKey : notnull
Adds a range of key/value pairs to the dictionary. Each item from the specified collection is added to the dictionary if the key generated by the key selector does not already exist in the dictionary. - DisposeCollection<TKey, TValue>()
Disposes of all disposable items within the dictionary. Each item in the dictionary that implements IDisposable will be disposed. - GetOrAdd<TKey, TValue>(TKey key, TValue value) where TKey : notnull where TValue : notnull
Gets the value associated with the specified key or adds it if the key does not exist. - IsNotEmpty<TKey, TValue>(Func<KeyValuePair<TKey, TValue>, bool> actionPredicate)
Determines whether the dictionary has any items that match the specified condition. - ToConcurrentDictionary()
Converts an IDictionary into a ConcurrentDictionary. - ToDelimitedString<TKey, TValue>([ConstantExpected] char delimiter) where TKey : notnull
Converts the dictionary’s items into a delimited string, utilizing a StringBuilder from an ObjectPool for enhanced performance. - ToFrozen()
Converts an IDictionary into a FrozenDictionary. - ToImmutable()
Converts an IDictionary into an ImmutableDictionary. - ToImmutableSorted()
Converts an IDictionary into an ImmutableSortedDictionary. - ToLookupWithDefault<TKey, TValue>(TValue defaultValue)
Creates a lookup function from the specified dictionary that returns the value for a given key, or a provided default value when the key is not present. - ToReadOnly()
Converts an IDictionary into a ReadOnlyDictionary.
This method is overloaded to use a IComparer<TKey>. - ToSorted()
Converts an IDictionary into a SortedDictionary. - TryGetValue<TKey, TValue>(TKey key, Func<TKey, TValue> valueFunction) where TKey : notnull where TValue : notnull
Tries to get the value associated with the specified key. If the key does not exist, uses the specified function to generate a value, which is then added to the dictionary. - Upsert<TKey, TValue>(TValue item)
Upserts the specified item into the IDictionary<TKey, TValue>. Validates that the collection and item are not null.
Summary
The DictionaryExtensions class removes much of the repetitive, error-prone code commonly associated with dictionary operations in .NET. By encapsulating best practices—such as safe insertion, efficient bulk operations, deterministic conversions, and allocation-conscious string generation—these extensions make dictionary usage cleaner, faster, and more reliable.
If your applications rely heavily on key/value data structures, DictionaryExtensions provides a consistent, high-performance foundation that improves readability, reduces bugs, and aligns your code with modern .NET design and performance principles.
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.

