Coding Faster with dotNetTips.com Spargine 8: February 2025 Release

I am delighted to announce the release of Spargine 8 (v2025.8.2.1) on February 1st, 2025. Spargine, my open-source project, now offers NuGet packages for .NET 8 & 9. These enhancements have been integrated across all my projects, many of which are currently in production. I encourage you to explore these updates and share any feedback or suggestions for further improvements.

This update introduces new classes, methods, benchmarks, and comprehensive unit tests (almost 300 new tests), all aimed at improving Spargine’s performance and reliability! Notably, this release includes speed enhancements informed by benchmark tests outlined in the 4th edition of Rock Your Code: Code & App Performance for Microsoft .NET, available on Amazon.

GitHub: https://github.com/RealDotNetDave/dotNetTips.Spargine.8/releases

NuGet: http://bit.ly/dotNetDaveNuGet

You can access all the performance data for these assemblies on GitHub. I continually seek assistance with these projects. If you are interested in contributing, please don’t hesitate to contact me via email at dotnetdave@live.com. Your support and collaboration are highly appreciated!

New Classes

Below is a detailed overview of the new classes introduced in this version of Spargine, highlighting their functionality and intended use cases.

AutoDefaultDictionary

The AutoDefaultDictionary is a specialized dictionary type that automatically returns a predefined default value when a key is not found. This eliminates the need for explicit error handling or null checks when accessing non-existent keys.

This type was inspired by an insightful article by Simon Painter, which sparked my interest in implementing it as part of Spargine. Below is an example of how to use this new type.

var dictionary = new AutoDefaultDictionary<string, Coordinate>(coordinates, defaultCoordinate);

var result = dictionary["notincollection"];

In this example, the key “notincollection” does not exist in the dictionary, so instead of throwing an exception, the defaultCoordinate object is returned automatically.

This ensures smoother code execution, reducing unnecessary exception handling and improving overall efficiency.

If you find AutoDefaultDictionary useful and have suggestions for enhancements, feel free to submit a feature request on GitHub!

Comparers

The following comparer have been introduced in the DotNetTips.Spargine.Core assembly to enhance the functionality of sorted collections:

  • OrdinalStringComparer: Implements an ordinal comparison for string objects, providing a fast and culture-invariant method of comparing strings.

Additionally, the DotNetTips.Spargine.Tester assembly now includes the following comparers, which are designed for sorting collections of the Person type. These comparers work efficiently with both reference and value types:

  • PersonAddressComparerByLastName: Compares KeyValuePair<TKey, TValue> objects where the value is a Person<Address>, sorting based on the person’s last name.
  • PersonComparerByLastName: Compares Person objects, sorting them based on the individual’s last name.
  • PersonComparerByLastNameThenFirstName: Provides a comparison for Person objects based on their last names and then first names.
  • PersonEmailEqualityComparer: Provides equality comparison for Person objects based on the email addresses.
  • PersonRecordEmailEqualityComparer: Provides equality comparison for PersonRecord objects based on the email address.

These additions help streamline sorting logic, making it easier to manage and query collections of person-related data.

New Methods

The latest release of Spargine introduces several powerful new methods, enhancing the library’s utility and versatility. Below is an overview of the newly added features:

Clock Enhancements

  • Clock.IsLeapYear(int year): Determines whether the specified year is a leap year.
  • Clock.TickCount64(): Retrieves the current tick count as a 64-bit integer.

CountryRepository Enhancements

The Countries type, was previously part of the DotNetTips.Spargine.8.Tester assembly has been moved to the DotNetTips.Spargine.8.Core assembly and renamed CountryRepository. This change supports the implementation of new, powerful methods that enhance functionality and usability.

New Methods

  1. ValidatePhoneNumber(CountryName countryName, string phoneNumber, bool validateCountryCode)
    1. Description: Validates the specified phone number for a given country.
    1. Features:
      1. If validateCountryCode is true, the method ensures the country code is included and correctly formatted as part of the phone number.
      1. Provides comprehensive validation to ensure the phone number meets the country-specific requirements.
  2. ValidatePostalCode(CountryName countryName, string postalCode)
    1. Description: Ensures that the given postal code is valid for the specified country.
    1. Features:
      1. Utilizes country-specific rules and patterns to validate the format of postal codes.
      1. Provides an efficient way to ensure geographic data accuracy in applications.

These enhancements improve the accuracy and reliability of country-specific data validation, making the CountryRepository a robust tool for globalized applications.

Dictionary Enhancements

  • DictionaryExtensions.ToLookupWithDefault<TKey, TValue>(TValue> defaultValue): Converts a dictionary into a lookup function that returns a value for a given key or a default value if the key is not found. Inspired by an article by Simon Painter.
  • DictionaryExtensions.ToSortedDictionary(IDictionary<TKey, TValue> collection, IComparer<TKey> comparer): Converts a IDictionary to a SortedDictionary using the specified comparer.
  • DictionaryExtensions.TryGetValue<TKey, TValue>(TKey key, Func<TValue> valueFunction): Attempts to retrieve the value associated with the given key. If the key is missing, the specified function generates a value, which is then added to the dictionary. Inspired by an article by Simon Painter.

IEnumerable Enhancements

  • EnumerableExtensions.IndexOf<T>(Func<T, bool> accumulatorPredicate): Finds the index of the first occurrence of an item in the collection that matches the specified predicate. Inspired by an article by Simon Painter.
  • EnumerableExtensions.ReplaceIf<T>(Func<T, int, bool> accumulatorPredicate, T replacement): Replaces elements in the collection based on a specified condition. Inspired by an article by Simon Painter.
  • EnumerableExtensions.Scan<T1, T2>(T2 seed, Func<T2, T1, T2> accumulatorFunction): Applies an accumulator function over a sequence. The specified seed value is used as the initial accumulator value, and the specified function is used to select the result value. Inspired by an article by Simon Painter.

InMemoryCache Enhancements

  • AddCacheItemAsync<T>(string key, T item): Asynchronously adds an item to the cache with a timeout of 20 minutes. This method is overloaded to accept TimeSpan or DateTimeOffset to set the expiration.
  • ContainsKey(): Determines whether the cache contains an item with the specified key.
  • GetAllKeys(): Gets all keys currently stored in the cache.
  • GetCacheItemAsync<T>(string key): Asynchronously gets the cache item associated with the specified key.
  • RemoveCacheItem(string key): Removes the cache item associated with the specified key.

List Enhancements

  • ListExtensions.AddRangeIfNotExists<T>(IEnumerable<T> items): Adds a range of items to a list only if they are not already present.
  • ListExtensions.RemoveFirst<T>(T item): Removes the first occurrence of a specified item from the list.
  • ListExtensions.RemoveLast<T>(T item): Removes the last occurrence of a specified item from the list.
  • ListExtensions.Shuffle<T>(): Randomly shuffles the elements of the list.
  • ListExtensions.Split<T>(int size): Splits the list into multiple smaller lists of the specified size.
  • ListExtensions.ToFastSortedList(List<T> collection, IComparer<T> comparer): Converts the List to a FastSortedList (Spargine collection) using the specified comparer.
  • ListExtensions.ToFrozenSet<T>(): Converts a List<T> to a FrozenSet<T>.

Object Enhancements

  • ObjectExtensions.FastGetHashCode(object obj): Provides an optimized method to compute a hash code for an object, enhancing performance when working with large collections or when using objects as keys in hash-based collections.

Security & Password Management

  • PasswordGenerator.GeneratePassword(int length): Generates a random password of the specified length, containing a mix of uppercase letters, lowercase letters, digits, and special characters.

Serialization Enhancements

  • JsonSerialization.LoadCollectionFromJson(string json, int count): Reads JSON content from a specified file and deserializes it into an object, and uses count to return the number of objects to deserialize from the JSON string.

String & StringBuilder Enhancements

  • RegexProcessor.GetNumbers(string input): Extracts all numeric characters from the input string.
  • RegexProcessor.IsIPv4Address(string input): Checks if the input is a valid IPv4 address.
  • RegexProcessor.IsIPv6Address(string input): Checks if the input is a valid IPv6 address.
  • RegexProcessor.IsOneToSevenAlpha(string input): Determines if the input string contains only alphabetic characters and has a length between 1 and 7 characters.
  • RegexProcessor.IsScientific(string input): Determines if the input string is in scientific notation.
  • StringBuilderExtensions.ClearSetCapacity(int capacity): Clears the StringBuilder and resets its capacity. This ensures that the StringBuilder is fully cleared when retrieved from an ObjectPool.
  • StringExtensions.CalculateByteArraySize(string input): Computes the size of a byte array needed to store the Base64-encoded version of the input string.
  • StringExtensions.ToBase64ByteSpan(string base64String): Converts a Base64-encoded string into a byte span.

Type & Reflection Utilities

  • TypeHelper.GetTypeDisplayName(Type type, DisplayNameOptions options): Gets the display name of the specified type using the provided display options.
  • TypeHelper.GetMembersWithAttribute<T>(Type type): Retrieves all members of a given type that have the specified attribute.
  • TypeHelper.ProcessGenericType(Type type): Constructs a display name for a generic type, including proper handling of generic arguments.

Obsolete Methods

As part of Spargine’s continuous improvements, I periodically review and refine the library to enhance usability and maintainability. Typically, I delay breaking changes until the end of the year to minimize disruptions for users. Below is a list of deprecated methods and their recommended replacements:

Updated Method Replacements

  • InformationAttribute.UnitTestCoverage → Use UnitTestStatus instead.
  • DateTimeExtensions.FromUnixTime → Use FromMilliEpochTime() instead.
  • DateTimeExtensions.ToUnixTime → Use ToMilliEpochTime() instead.
  • DateTimeExtensions.NextDayOfWeek → Use GetNextDayOfWeek() instead. (Duplicate removed)
  • ListExtensions.CopyToCollection → Use ToCollection() instead.

These updates ensure Spargine remains consistent, intuitive, and aligned with modern development practices. If you have any questions or need migration guidance, feel free to reach out!

Summary

I trust these new and enhanced methods in Spargine will significantly benefit your projects by boosting performance and reliability. Detailed benchmark results are available on GitHub. As always, the success of open-source projects like Spargine relies heavily on community involvement. If you find these updates useful or if you have ideas for further improvements, I encourage you to contribute. Whether it is by submitting a pull request, reporting issues, or suggesting new features, your input is invaluable.

Together, we can continue to make Spargine a robust and indispensable tool for the .NET community. Your feedback and suggestions are highly appreciated, so please share them in the comments section. Thank you for your support and keep coding faster and better!

Pick up any books by David McCarter by going to Amazon.com: http://bit.ly/RockYourCodeBooks

One-Time
Monthly
Yearly

Make a one-time donation

Make a monthly donation

Make a yearly donation

Choose an amount

$5.00
$15.00
$100.00
$5.00
$15.00
$100.00
$5.00
$15.00
$100.00

Or enter a custom amount

$

Your contribution is appreciated.

Your contribution is appreciated.

Your contribution is appreciated.

DonateDonate monthlyDonate yearly

If 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.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.