ktsu.Extensions 1.5.2

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package ktsu.Extensions --version 1.5.2
                    
NuGet\Install-Package ktsu.Extensions -Version 1.5.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ktsu.Extensions" Version="1.5.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ktsu.Extensions" Version="1.5.2" />
                    
Directory.Packages.props
<PackageReference Include="ktsu.Extensions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ktsu.Extensions --version 1.5.2
                    
#r "nuget: ktsu.Extensions, 1.5.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=ktsu.Extensions&version=1.5.2
                    
Install ktsu.Extensions as a Cake Addin
#tool nuget:?package=ktsu.Extensions&version=1.5.2
                    
Install ktsu.Extensions as a Cake Tool

ktsu.Extensions

A comprehensive utility library of extension methods for collections, strings, dictionaries, and reflection in .NET.

License NuGet NuGet Downloads Build Status GitHub Stars

Introduction

ktsu.Extensions is a utility library that enhances the functionality of standard .NET types through extension methods. It provides a wide range of utilities for explicit shallow and deep cloning, batch operations, string manipulations, and reflection helpers, making it easier to work with common data structures and types in a consistent, null-safe manner.

Features

  • Enumerable Extensions

    • WithIndex: Enumerates over an enumerable with the index of the item
    • ToCollection: Converts an enumerable to a collection
    • ForEach: Applies an action to each element of an enumerable
    • DeepClone/ShallowClone: Creates clones of a collection of items
    • AnyNull: Checks if the enumerable contains any null items
  • Collection Extensions

    • AddMany: Adds items from an enumerable to a collection
    • ToStringCollection: Converts a collection to a collection of strings
  • Dictionary Extensions

    • GetOrCreate: Gets the value for a key or creates a new value if the key doesn't exist
    • AddOrReplace: Adds a new value or replaces an existing value
    • DeepClone/ShallowClone: Creates clones of a dictionary
  • String Extensions

    • As<TDest>: Converts between string types
    • Ordinal comparison helpers (StartsWithOrdinal, EndsWithOrdinal, ContainsOrdinal)
    • Prefix/suffix manipulation (RemoveSuffix, RemovePrefix)
    • Line ending utilities (DetermineLineEndings, NormalizeLineEndings)
  • Reflection Extensions

    • TryFindMethod: Searches for methods across inheritance hierarchies

Installation

Package Manager Console

Install-Package ktsu.Extensions

.NET CLI

dotnet add package ktsu.Extensions

Package Reference

<PackageReference Include="ktsu.Extensions" Version="x.y.z" />

Usage Examples

Enumerable Extensions

using ktsu.Extensions;

// Iterate with index
foreach (var (item, index) in myList.WithIndex())
{
    Console.WriteLine($"Item at position {index}: {item}");
}

// Apply action to each item
myList.ForEach(item => Console.WriteLine(item));

// Create clones
var deepClone = myList.DeepClone();
var shallowClone = myList.ShallowClone();

// Check for nulls
if (myList.AnyNull())
{
    Console.WriteLine("List contains null items");
}

String Extensions

using ktsu.Extensions;

string text = "Hello, World!";

// Ordinal string comparisons
if (text.StartsWithOrdinal("Hello"))
{
    Console.WriteLine("Text starts with 'Hello'");
}

// Prefix/suffix manipulation
string withoutPrefix = text.RemovePrefix("Hello, ");  // "World!"
string withoutSuffix = text.RemoveSuffix("!");        // "Hello, World"

// Line ending handling
string mixedText = "Line1\r\nLine2\nLine3";
var lineEndingStyle = mixedText.DetermineLineEndings();  // LineEndingStyle.Mixed
string normalized = mixedText.NormalizeLineEndings(LineEndingStyle.Unix);  // All \n

Dictionary Extensions

using ktsu.Extensions;

var cache = new Dictionary<string, List<string>>();

// Get or create a value
var items = cache.GetOrCreate("key", () => new List<string>());
items.Add("item1");

// Add or replace a value
cache.AddOrReplace("key2", new List<string> { "item2" });

// Clone the dictionary
var deepClone = cache.DeepClone();

Advanced Usage

Working with StrongStrings

using ktsu.Extensions;
using ktsu.StrongStrings;

// Convert a regular string to a strong string
var strongId = "12345".As<ID>();

// Apply string extensions to strong strings
if (strongId.StartsWithOrdinal("123"))
{
    // Do something with the strong string
}

Null Item Handling

using ktsu.Extensions;

var items = new[] { "one", null, "three" };

// Convert to strings with null handling
var strings1 = items.ToStringEnumerable(NullItemHandling.Skip);       // ["one", "three"]
var strings2 = items.ToStringEnumerable(NullItemHandling.UseEmpty);   // ["one", "", "three"]
var strings3 = items.ToStringEnumerable(NullItemHandling.UseNull);    // ["one", null, "three"]
var strings4 = items.ToStringEnumerable(NullItemHandling.UseDefault); // ["one", "(null)", "three"]

Reflection Helpers

using ktsu.Extensions;
using System.Reflection;

// Find a method across inheritance hierarchy
if (someType.TryFindMethod("MethodName", BindingFlags.Instance | BindingFlags.Public, out var methodInfo))
{
    // Use the method info
    methodInfo.Invoke(instance, parameters);
}

API Reference

String Extensions

Method Description
As<TDest> Converts a string to a strong string type
StartsWithOrdinal Checks if string starts with value using ordinal comparison
EndsWithOrdinal Checks if string ends with value using ordinal comparison
ContainsOrdinal Checks if string contains value using ordinal comparison
RemovePrefix Removes a prefix from a string if present
RemoveSuffix Removes a suffix from a string if present
ReplaceOrdinal Replaces text using ordinal comparison
DetermineLineEndings Identifies line ending style in a string
NormalizeLineEndings Converts line endings to a specific style

Collection Extensions

Method Description
AddMany Adds multiple items to a collection
AnyNull Checks if collection contains any null items
ToStringCollection Converts collection to string collection
WriteItemsToConsole Displays collection items in console

Dictionary Extensions

Method Description
GetOrCreate Gets existing value or creates new one
AddOrReplace Adds a new value or replaces existing one
DeepClone Creates a deep copy of the dictionary
ShallowClone Creates a shallow copy of the dictionary

Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Please make sure to update tests as appropriate.

License

This project is licensed under the MIT License - see the LICENSE.md file for details.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (8)

Showing the top 5 NuGet packages that depend on ktsu.Extensions:

Package Downloads
ktsu.StrongPaths

A library that provides strong typing for common filesystem paths providing compile time feedback and runtime validation.

ktsu.ToStringJsonConverter

A JSON converter for System.Text.Json that handles ToString and Parse methods for value types.

ktsu.ImGuiStyler

A library for expressively styling ImGui.NET interfaces.

ktsu.ImGuiWidgets

A library of custom widgets using ImGui.NET and utilities to enhance ImGui-based applications.

ktsu.ImGuiPopups

A library for custom popups using ImGui.NET.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.5.6-pre.2 0 5/20/2025
1.5.5 85 5/18/2025
1.5.4 63 5/18/2025
1.5.4-pre.15 33 5/17/2025
1.5.4-pre.14 113 5/16/2025
1.5.4-pre.13 181 5/15/2025
1.5.4-pre.12 183 5/14/2025
1.5.4-pre.11 186 5/13/2025
1.5.4-pre.10 214 5/12/2025
1.5.4-pre.9 151 5/11/2025
1.5.4-pre.8 97 5/10/2025
1.5.4-pre.7 33 5/9/2025
1.5.4-pre.6 105 5/8/2025
1.5.4-pre.5 112 5/7/2025
1.5.4-pre.4 103 5/6/2025
1.5.4-pre.3 110 5/5/2025
1.5.4-pre.2 108 5/4/2025
1.5.4-pre.1 108 5/4/2025
1.5.3 393 5/4/2025
1.5.3-pre.1 42 4/26/2025
1.5.2 443 4/25/2025
1.5.2-pre.1 105 4/4/2025
1.5.1 626 3/30/2025
1.5.0 1,449 3/30/2025
1.4.1 95 3/29/2025
1.4.1-pre.3 62 3/29/2025
1.4.1-pre.2 445 3/25/2025
1.4.1-pre.1 65 2/19/2025
1.4.0 3,266 2/18/2025
1.3.3-pre.5 63 2/17/2025
1.3.3-pre.4 64 2/11/2025
1.3.3-pre.3 72 2/6/2025
1.3.3-pre.2 59 2/5/2025
1.3.3-pre.1 60 2/5/2025
1.3.2 3,696 1/2/2025
1.3.2-pre.27 58 2/4/2025
1.3.2-pre.26 57 2/3/2025
1.3.2-pre.25 64 2/2/2025
1.3.2-pre.24 53 1/31/2025
1.3.2-pre.23 54 1/29/2025
1.3.2-pre.22 56 1/27/2025
1.3.2-pre.21 50 1/26/2025
1.3.2-pre.20 49 1/24/2025
1.3.2-pre.19 58 1/22/2025
1.3.2-pre.18 54 1/20/2025
1.3.2-pre.17 46 1/18/2025
1.3.2-pre.16 45 1/16/2025
1.3.2-pre.15 34 1/14/2025
1.3.2-pre.14 47 1/13/2025
1.3.2-pre.13 51 1/11/2025
1.3.2-pre.12 44 1/10/2025
1.3.2-pre.11 56 1/10/2025
1.3.2-pre.10 44 1/8/2025
1.3.2-pre.9 56 1/7/2025
1.3.2-pre.8 60 1/6/2025
1.3.2-pre.7 73 1/4/2025
1.3.2-pre.6 59 1/3/2025
1.3.2-pre.5 61 1/3/2025
1.3.2-pre.4 64 1/3/2025
1.3.2-pre.3 73 1/1/2025
1.3.2-pre.2 79 12/31/2024
1.3.2-pre.1 61 12/29/2024
1.3.1 2,976 12/28/2024
1.3.0 87 12/28/2024
1.2.16-pre.3 52 12/28/2024
1.2.16-pre.2 55 12/27/2024
1.2.16-pre.1 57 12/27/2024
1.2.15-pre.1 56 12/27/2024
1.2.14 901 12/26/2024
1.2.13 92 12/26/2024
1.2.12 90 12/26/2024
1.2.11 89 12/26/2024
1.2.10 89 12/26/2024
1.2.10-pre.1 55 12/27/2024
1.2.9 97 12/26/2024
1.2.8 2,592 12/26/2024
1.2.7 1,818 12/24/2024
1.2.6 490 12/23/2024
1.2.5 87 12/23/2024
1.2.4 441 12/22/2024
1.2.3 106 12/22/2024
1.2.2 141 12/22/2024
1.2.1 152 12/22/2024
1.2.0 629 12/19/2024
1.1.0 90 12/19/2024
1.0.37 537 12/13/2024
1.0.36 668 12/5/2024
1.0.35 340 12/4/2024
1.0.34 454 12/2/2024
1.0.33 91 12/2/2024
1.0.32 294 12/2/2024
1.0.31 422 12/1/2024
1.0.30 226 12/1/2024
1.0.29 91 12/1/2024
1.0.28 158 11/30/2024
1.0.27 274 11/28/2024
1.0.26 307 11/26/2024
1.0.25 1,104 11/14/2024
1.0.24 318 11/13/2024
1.0.23 815 11/2/2024
1.0.22 369 11/1/2024
1.0.21 1,056 10/16/2024
1.0.20 686 10/5/2024
1.0.19 229 10/4/2024
1.0.18 776 9/21/2024
1.0.17 279 9/19/2024
1.0.16 102 9/19/2024
1.0.15 278 9/19/2024
1.0.14 205 9/19/2024
1.0.13 210 9/19/2024
1.0.12 132 9/18/2024
1.0.11 112 9/18/2024
1.0.10 172 9/18/2024
1.0.9 634 9/18/2024
1.0.8 452 9/14/2024
1.0.7 130 9/14/2024

## v1.5.2 (patch)

Changes since v1.5.1:

- Update README to match standard template format ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.5.1 (patch)

Changes since v1.5.0:

- Update packages ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.5.0 (minor)

Changes since v1.4.0:

- Add LICENSE template ([@matt-edmondson](https://github.com/matt-edmondson))
- Update packages ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.4.1 (patch)

Changes since v1.4.0:

- Update packages ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.4.0 (minor)

Changes since v1.3.0:

- Add automation scripts for metadata management and versioning ([@matt-edmondson](https://github.com/matt-edmondson))
- Add mailmap ([@matt-edmondson](https://github.com/matt-edmondson))
- Apply new editorconfig ([@matt-edmondson](https://github.com/matt-edmondson))
- Refactor LineEndingStyle enumeration to standalone ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.3.2 (patch)

Changes since v1.3.1:

- Add automation scripts for metadata management and versioning ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.3.1 (patch)

Changes since v1.3.0:

- Refactor LineEndingStyle enumeration to standalone ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.3.0 (minor)

Changes since v1.2.0:

- Add line ending methods and tests, update README ([@matt-edmondson](https://github.com/matt-edmondson))
- Refactor test method names and update LICENSE ([@matt-edmondson](https://github.com/matt-edmondson))
- Renamed metadata files ([@matt-edmondson](https://github.com/matt-edmondson))
- Replace LICENSE file with LICENSE.md and update copyright information ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.2.10 (patch)

Changes since v1.2.9:

- Replace LICENSE file with LICENSE.md and update copyright information ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.2.8 (patch)

Changes since v1.2.7:

- Refactor test method names and update LICENSE ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.2.0 (minor)

Changes since v1.1.0:

- Add comprehensive unit tests for Join method ([@matt-edmondson](https://github.com/matt-edmondson))
- Add Join extension methods to EnumerableExtensions ([@matt-edmondson](https://github.com/matt-edmondson))
- Update README.md to document new Join extension method ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.1.0 (minor)

Changes since v1.0.0:

- Add a locket overload of ForEach ([@matt-edmondson](https://github.com/matt-edmondson))
- Add AddOrReplace method to DictionaryExtensions ([@matt-edmondson](https://github.com/matt-edmondson))
- Add an overload to ToCollection that takes an object to acquire a lock on while enumerating ([@matt-edmondson](https://github.com/matt-edmondson))
- Add collection handling and conversion extensions ([@matt-edmondson](https://github.com/matt-edmondson))
- Add CollectionExtensions with AddMany method ([@matt-edmondson](https://github.com/matt-edmondson))
- Add DeepClone enumerable extension ([@matt-edmondson](https://github.com/matt-edmondson))
- Add DeepClone for dictionaries ([@matt-edmondson](https://github.com/matt-edmondson))
- Add new tests and refactor extension methods ([@matt-edmondson](https://github.com/matt-edmondson))
- Add new unit tests ([@matt-edmondson](https://github.com/matt-edmondson))
- Add ShallowClone to enumerables and dictionaries ([@matt-edmondson](https://github.com/matt-edmondson))
- Add string.As<StrongStrong>() ([@matt-edmondson](https://github.com/matt-edmondson))
- Add support for GetOrCreate on concurrent dictionaries ([@matt-edmondson](https://github.com/matt-edmondson))
- Fix Dictionary return types ([@matt-edmondson](https://github.com/matt-edmondson))
- Migrate ktsu.io to ktsu namespace ([@matt-edmondson](https://github.com/matt-edmondson))
- Minor code style changes ([@matt-edmondson](https://github.com/matt-edmondson))
- Update DESCRIPTION and overhaul README.md ([@matt-edmondson](https://github.com/matt-edmondson))
- Update package references and add ILCompiler dependency ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.0.31 (patch)

Changes since v1.0.30:

- Update package references and add ILCompiler dependency ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.0.30 (patch)

Changes since v1.0.29:

- Add new tests and refactor extension methods ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.0.29 (patch)

Changes since v1.0.28:

- Add collection handling and conversion extensions ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.0.14 (patch)

Changes since v1.0.13:

- Add string.As<StrongStrong>() ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.0.8 (patch)

Changes since 1.0.7:

- Migrate ktsu.io to ktsu namespace ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.0.0 (major)

Changes since 0.0.0.0:

- Add an overload of GetOrCreate for dictionaries that takes a supplied default value ([@matt-edmondson](https://github.com/matt-edmondson))
- Add DictionaryExtensions.GetOrCreate() ([@matt-edmondson](https://github.com/matt-edmondson))
- Add EnumerableExtensions hoisted from ImGuiApp ([@matt-edmondson](https://github.com/matt-edmondson))
- Add ForEach to enumerable extensions ([@matt-edmondson](https://github.com/matt-edmondson))
- Add github package support ([@matt-edmondson](https://github.com/matt-edmondson))
- Add IEnumerable.ToCollection ([@matt-edmondson](https://github.com/matt-edmondson))
- Add ReplaceOrdinal for strings ([@matt-edmondson](https://github.com/matt-edmondson))
- Add String extensions for StrongStrings ([@matt-edmondson](https://github.com/matt-edmondson))
- Added RemoveSuffix and RemovePrefix ([@matt-edmondson](https://github.com/matt-edmondson))
- Assign dependabot PRs to matt ([@matt-edmondson](https://github.com/matt-edmondson))
- Avoid double upload of symbols package ([@matt-edmondson](https://github.com/matt-edmondson))
- Create dependabot-merge.yml ([@matt-edmondson](https://github.com/matt-edmondson))
- Create VERSION ([@matt-edmondson](https://github.com/matt-edmondson))
- Dont try to push packages when building pull requests ([@matt-edmondson](https://github.com/matt-edmondson))
- Enable dependabot and sourcelink ([@matt-edmondson](https://github.com/matt-edmondson))
- Initial commit ([@matt-edmondson](https://github.com/matt-edmondson))
- Make Dictionary.GetOrCreate not return a nullable ([@matt-edmondson](https://github.com/matt-edmondson))
- Migrate from .project.props to Directory.Build.props ([@matt-edmondson](https://github.com/matt-edmondson))
- Read from AUTHORS file during build ([@matt-edmondson](https://github.com/matt-edmondson))
- Read from VERSION when building ([@matt-edmondson](https://github.com/matt-edmondson))
- Read PackageDescription from DESCRIPTION file ([@matt-edmondson](https://github.com/matt-edmondson))
- Update .project.props ([@matt-edmondson](https://github.com/matt-edmondson))
- Update build config ([@matt-edmondson](https://github.com/matt-edmondson))
- Update build scripts ([@matt-edmondson](https://github.com/matt-edmondson))
- Update descriptions and readme ([@matt-edmondson](https://github.com/matt-edmondson))
- Update Directory.Build.props ([@matt-edmondson](https://github.com/matt-edmondson))
- Update Directory.Build.targets ([@matt-edmondson](https://github.com/matt-edmondson))
- Update dotnet.yml ([@matt-edmondson](https://github.com/matt-edmondson))
- Update LICENSE ([@matt-edmondson](https://github.com/matt-edmondson))
- Update nuget.config ([@matt-edmondson](https://github.com/matt-edmondson))
- Update readme ([@matt-edmondson](https://github.com/matt-edmondson))
- v1.0.0-alpha.8 ([@matt-edmondson](https://github.com/matt-edmondson))