AboExtensions 0.1.0

dotnet add package AboExtensions --version 0.1.0
                    
NuGet\Install-Package AboExtensions -Version 0.1.0
                    
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="AboExtensions" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AboExtensions" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="AboExtensions" />
                    
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 AboExtensions --version 0.1.0
                    
#r "nuget: AboExtensions, 0.1.0"
                    
#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.
#:package AboExtensions@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AboExtensions&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=AboExtensions&version=0.1.0
                    
Install as a Cake Tool

AboExtensions

A small collection of C# extension methods I kept rewriting in every project. Collected here once and for all.

Installation

dotnet add package AboExtensions

Quick reference

Namespace Methods
Booleans Toggle
Chars IsUnicodeLetter, IsVowel, IsConsonant, IsAscii, Repeat, Rot13, Luminosity
ComplexNumbers ToMathString
Dates IsWeekend, IsWeekday, StartOfDay, EndOfDay, StartOfWeek, Age, IsInThePast, IsInTheFuture, Quarter, AddWorkdays, NextWeekday, ToUnixTimestamp, ToUnixTimestampMs, FromUnixTimestamp, FromoUnixTimestampMs
Dictionaries AddOrUpdate, Invert
Enums GetValues
Exceptions GetRootCause, Flatten
Guids IsEmpty, IsNotEmpty, OrNew
IpAddresses IsValidIp, IsValidIpV4, IsValidIpV6, ToIpAddress
Lists ForEach, None, IsNullOrEmpty, Batch, Shuffle, WhereNotNull, Flatten, Frequencies
Numbers Or, Clamp, IsBetween, Abs, Percentage, Round, IsNanOrInf, IsNotNanNorInf, IsEven, IsOdd, Digits, ToOrdinal, RomanEncode, RomanDecode
Nullables IfNotNull, MapNotNull
Objects IsNull, IsNotNull, Also, Let, In, NotIn
Randoms NextBool, NextItem, RandomItem, NextEnum, NextString
Reflections GetPropertyByName, GetPropertiesToString
StringBuilders AppendIf, AppendLineIf, Prepend
Strings IsNullOrWhiteSpace, IsNotNullOrWhiteSpace, IsNullOrEmpty, IsNotNullOrEmpty, OrElse, Capitalize, ToSlug, ToPascalCase, ToCamelCase, Repeat, Left, Right, Ellipsify, NumOnly, CharOnly, IsNumeric, IsEmail, TrimStartEnd, StringJoin, RemoveFirstChar
TimeSpans IsZero, Ago, FromNow

Strings (AboExtensions.Strings)

using AboExtensions.Strings;

Null/empty checks - readable versions of string.IsNullOrWhiteSpace and friends, callable directly on the variable:

if (name.IsNullOrWhiteSpace()) ...       // null, "" and "   " → true
if (name.IsNotNullOrWhiteSpace()) ...    // opposite, with [NotNullWhen(true)]
if (name.IsNullOrEmpty()) ...            // only null and ""
if (name.IsNotNullOrEmpty()) ...

OrElse - returns a fallback value if the string is empty or null:

var title = input.OrElse("Untitled");
// if input is null, "" or "   " → "Untitled"
// to ignore whitespace: .OrElse("default", alsows: false)

Capitalize - uppercases the first letter, lowercases the rest. Pass keepOthers: true to leave the remaining characters unchanged:

"hello".Capitalize()                    // → "Hello"
"WORLD".Capitalize()                    // → "World"
"hELLO".Capitalize(keepOthers: true)    // → "HELLO" (only first char uppercased)

ToSlug - converts a string to a URL-friendly slug:

"Hello World".ToSlug()       // → "hello-world"
"C# is great!".ToSlug()     // → "c-is-great"

ToPascalCase / ToCamelCase - converts a phrase (spaces, dashes, any separator) to PascalCase or camelCase:

"hello world".ToPascalCase()    // → "HelloWorld"
"foo bar baz".ToCamelCase()     // → "fooBarBaz"
"already-slug".ToPascalCase()   // → "AlreadySlug"
"UPPER CASE".ToCamelCase()      // → "upperCase"

Repeat - repeats a string n times:

"ab".Repeat(3)    // → "ababab"
"x".Repeat(0)     // → ""

Left / Right - safe substring from the left or right:

"hello".Left(3)     // → "hel"
"hello".Right(3)    // → "llo"
"hi".Left(10)       // → "hi"  (no exception if n > length)

Ellipsify - truncates a string adding ... if it exceeds the max length:

"Hello world".Ellipsify(7)   // → "Hell..."
"Hello".Ellipsify(7)         // → "Hello"

NumOnly and CharOnly - filter out unwanted characters:

"abc123def456".NumOnly()              // → "123456"
"A1-B2/C3".CharOnly("ABC123")        // → "A1B2C3"

IsNumeric - checks whether the string represents a number:

"42".IsNumeric()     // → true
"abc".IsNumeric()    // → false

IsEmail - basic structural email validation (no regex):

"user@example.com".IsEmail()    // → true
"noatsign".IsEmail()            // → false
"user@".IsEmail()               // → false

TrimStartEnd - like Trim but for a specific character:

"/path/".TrimStartEnd('/')    // → "path"

StringJoin - string.Join as an extension on a collection:

new[] { "a", "b", "c" }.StringJoin(", ")    // → "a, b, c"

RemoveFirstChar - removes the first character if it matches the given one:

"/api/users".RemoveFirstChar('/')    // → "api/users"
"api/users".RemoveFirstChar('/')     // → "api/users" (unchanged)

Numbers (AboExtensions.Numbers)

using AboExtensions.Numbers;

Or - default value for nullable numbers (float?, int?, double?, decimal?):

float? f = null;   f.Or()      // → 0f
int? i = null;     i.Or(99)    // → 99
double? d = null;  d.Or()      // → 0.0
decimal? m = null; m.Or(9.9m)  // → 9.9m

Clamp - constrains a value within a min/max range, for int, double, and decimal:

15.Clamp(1, 10)       // → 10
0.Clamp(1, 10)        // → 1
5.0.Clamp(1.0, 10.0)  // → 5.0

IsBetween - range check, inclusive by default:

5.IsBetween(1, 10)                    // → true
1.IsBetween(1, 10)                    // → true  (inclusive)
1.IsBetween(1, 10, inclusive: false)  // → false (exclusive)

Abs - absolute value as an extension, for int and double:

(-5).Abs()     // → 5
(-3.14).Abs()  // → 3.14

Percentage - calculates what percentage part is of total:

50.0.Percentage(200.0)    // → 25.0
5.0.Percentage(0.0)       // → 0.0  (safe division by zero)

Round - rounding with decimal places, on double and decimal:

3.14159.Round(2)    // → 3.14
2.555m.Round(2)     // → 2.56

IsNanOrInf / IsNotNanNorInf - checks for abnormal float values:

float.NaN.IsNanOrInf()              // → true
float.PositiveInfinity.IsNanOrInf() // → true
3.14f.IsNotNanNorInf()              // → true

IsEven / IsOdd - parity checks on int:

4.IsEven()    // → true
3.IsOdd()     // → true
0.IsEven()    // → true

Digits - number of digits in an integer (sign ignored), optionally in a given base:

123.Digits()      // → 3
0.Digits()        // → 1
(-42).Digits()    // → 2
255.Digits(2)     // → 8  (11111111₂)
255.Digits(16)    // → 2  (FF₁₆)

ToOrdinal - converts an integer to its English ordinal string, handles the 11th/12th/13th special cases:

1.ToOrdinal()     // → "1st"
2.ToOrdinal()     // → "2nd"
3.ToOrdinal()     // → "3rd"
4.ToOrdinal()     // → "4th"
11.ToOrdinal()    // → "11th"
21.ToOrdinal()    // → "21st"

RomanEncode - converts a positive integer to a Roman numeral string. Range: 1–3999:

1.RomanEncode()       // → "I"
4.RomanEncode()       // → "IV"
1994.RomanEncode()    // → "MCMXCIV"
3999.RomanEncode()    // → "MMMCMXCIX"
// throws ArgumentOutOfRangeException if outside 1–3999

RomanDecode - converts a Roman numeral string to an integer. Case-insensitive:

"XIV".RomanDecode()     // → 14
"MCMXCIV".RomanDecode() // → 1994
"xiv".RomanDecode()     // → 14

Lists (AboExtensions.Lists)

using AboExtensions.Lists;

ForEach - executes an action for each element of any IEnumerable (LINQ doesn't have this):

new[] { 1, 2, 3 }.ForEach(x => Console.WriteLine(x));

None - the opposite of Any: returns true if no element satisfies the predicate:

new[] { 1, 2, 3 }.None(x => x > 10)    // → true
new[] { 1, 2, 3 }.None(x => x > 2)     // → false

IsNullOrEmpty - checks if a collection is null or empty:

((IEnumerable<int>?)null).IsNullOrEmpty()    // → true
Array.Empty<int>().IsNullOrEmpty()           // → true
new[] { 1 }.IsNullOrEmpty()                 // → false

Batch - splits a sequence into chunks of the given size; the last batch may be smaller:

new[] { 1, 2, 3, 4, 5 }.Batch(2)   // → [[1,2], [3,4], [5]]
new[] { 1, 2 }.Batch(10)            // → [[1,2]]

Shuffle - returns a new shuffled list (Fisher-Yates), does not mutate the original:

new List<int> { 1, 2, 3, 4, 5 }.Shuffle()   // → e.g. [3, 1, 5, 2, 4]

WhereNotNull - filters null elements from a sequence; the return type is non-nullable. Works for both reference types and nullable value types:

new[] { "a", null, "b" }.WhereNotNull()    // → ["a", "b"]
new int?[] { 1, null, 3 }.WhereNotNull()   // → [1, 3]

Flatten - flattens a sequence of sequences into a single list:

new[] { new[] { 1, 2 }, new[] { 3, 4 } }.Flatten()   // → [1, 2, 3, 4]
new[] { new[] { "a" }, new[] { "b", "c" } }.Flatten() // → ["a", "b", "c"]

Frequencies - counts occurrences of each element, returning a Dictionary<T, int>:

new[] { "a", "b", "a", "c", "a", "b" }.Frequencies()
// → { "a": 3, "b": 2, "c": 1 }

new[] { 1, 2, 1, 1 }.Frequencies()
// → { 1: 3, 2: 1 }

Dates (AboExtensions.Dates)

using AboExtensions.Dates;

IsWeekend / IsWeekday - checks whether the date falls on a weekend or weekday:

new DateTime(2024, 1, 6).IsWeekend()   // Saturday → true
new DateTime(2024, 1, 8).IsWeekday()   // Monday   → true

StartOfDay / EndOfDay - returns midnight or the last tick of the day:

new DateTime(2024, 6, 15, 14, 30, 0).StartOfDay()  // → 2024-06-15 00:00:00.000
new DateTime(2024, 6, 15, 14, 30, 0).EndOfDay()    // → 2024-06-15 23:59:59.999...

StartOfWeek - returns the first day of the week containing the date (default: Monday):

new DateTime(2024, 1, 10).StartOfWeek()                    // Wednesday → 2024-01-08 (Monday)
new DateTime(2024, 1, 10).StartOfWeek(DayOfWeek.Sunday)    // Wednesday → 2024-01-07 (Sunday)

Age - calculates completed years from a birth date to today:

new DateTime(1990, 6, 15).Age()   // → 35  (as of 2025)

IsInThePast / IsInTheFuture - checks whether a date is before or after the current moment:

DateTime.Now.AddSeconds(-1).IsInThePast()    // → true
DateTime.Now.AddSeconds(1).IsInTheFuture()   // → true

Quarter - returns the quarter of the year (1–4):

new DateTime(2024, 4, 1).Quarter()    // → 2
new DateTime(2024, 12, 31).Quarter()  // → 4

AddWorkdays - adds (or subtracts) n working days, skipping weekends:

new DateTime(2024, 1, 5).AddWorkdays(3)    // Friday + 3 workdays → Wednesday 2024-01-10
new DateTime(2024, 1, 10).AddWorkdays(-3)  // Wednesday - 3 workdays → Friday 2024-01-05

NextWeekday - returns the next occurrence of a given day of the week:

new DateTime(2024, 1, 10).NextWeekday(DayOfWeek.Friday)   // Wednesday → 2024-01-12
new DateTime(2024, 1, 8).NextWeekday(DayOfWeek.Monday)    // Monday → next Monday 2024-01-15

ToUnixTimestamp / ToUnixTimestampMs — converts a DateTime to a Unix timestamp in seconds or milliseconds. Local is converted to UTC; Unspecified is treated as UTC by default (pass throwOnUnspecified: true to enforce strictness):

DateTime.UnixEpoch.ToUnixTimestamp()                                          // → 0
new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToUnixTimestamp()        // → 1704067200
new DateTime(2024, 1, 1, 0, 0, 0, 500, DateTimeKind.Utc).ToUnixTimestampMs() // → 1704067200500

FromUnixTimestamp / FromoUnixTimestampMs — converts a Unix timestamp back to a DateTime with Kind = Utc:

0L.FromUnixTimestamp()           // → DateTime.UnixEpoch (1970-01-01 00:00:00 UTC)
1704067200L.FromUnixTimestamp()  // → 2024-01-01 00:00:00 UTC

// round-trip:
dt.ToUnixTimestamp().FromUnixTimestamp() == dt   // → true

Booleans (AboExtensions.Booleans)

using AboExtensions.Booleans;

Toggle - returns the opposite boolean value:

true.Toggle()     // → false
false.Toggle()    // → true

isActive = isActive.Toggle();

Chars (AboExtensions.Chars)

using AboExtensions.Chars;

IsUnicodeLetter / IsVowel / IsConsonant - character classification:

'a'.IsUnicodeLetter()    // → true
'3'.IsUnicodeLetter()    // → false
'e'.IsVowel()            // → true
'b'.IsConsonant()        // → true

IsAscii - true if the character code is ≤ 127:

'A'.IsAscii()    // → true
'é'.IsAscii()    // → false

Repeat - repeats a character n times into a string:

'-'.Repeat(5)    // → "-----"
'x'.Repeat(0)    // → ""

Rot13 - applies the ROT13 cipher. Non-letter characters are unchanged:

'A'.Rot13()    // → 'N'
'n'.Rot13()    // → 'a'
'3'.Rot13()    // → '3'

Luminosity - returns the visual density of a character as a double in [0.0, 1.0], where ' ' is empty and '█' is full. Useful for ASCII art and terminal rendering:

' '.Luminosity()    // → 0.0
'.'.Luminosity()    // → 0.05
'i'.Luminosity()    // → 0.15
'a'.Luminosity()    // → 0.35  (Unicode category fallback)
'W'.Luminosity()    // → 0.65
'@'.Luminosity()    // → 0.75
'░'.Luminosity()    // → 0.25
'▒'.Luminosity()    // → 0.5
'▓'.Luminosity()    // → 0.75
'█'.Luminosity()    // → 1.0
// lower bar blocks are proportional (▁→0.125 … █→1.0)

Complex Numbers (AboExtensions.ComplexNumbers)

using AboExtensions.ComplexNumbers;

ToMathString - formats a complex number in standard mathematical notation a+bi, omitting zero parts and the coefficient 1 before i:

new Complex(1, 2).ToMathString()    // → "1+2i"
new Complex(1, -2).ToMathString()   // → "1-2i"
new Complex(0, 2).ToMathString()    // → "2i"
new Complex(1, 0).ToMathString()    // → "1"
new Complex(0, 0).ToMathString()    // → "0"
new Complex(0, 1).ToMathString()    // → "i"
new Complex(0, -1).ToMathString()   // → "-i"
new Complex(1, 1).ToMathString()    // → "1+i"

Dictionaries (AboExtensions.Dictionaries)

using AboExtensions.Dictionaries;

AddOrUpdate - adds or updates a key/value pair; returns the dictionary for chaining:

dict.AddOrUpdate("key", 42)    // adds if missing, overwrites if present

new Dictionary<string, int>()
    .AddOrUpdate("a", 1)
    .AddOrUpdate("b", 2);      // chaining

Invert - swaps keys and values. Throws ArgumentException on duplicate values by default:

new Dictionary<string, int> { ["a"] = 1, ["b"] = 2 }.Invert()
// → { 1: "a", 2: "b" }

// silently keep last value on duplicate:
dict.Invert(throwOnDuplicate: false)

Enums (AboExtensions.Enums)

using AboExtensions.Enums;

GetValues<T> - returns all values of an enum type:

EnumExtensions.GetValues<DayOfWeek>()
// → [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]

foreach (var status in EnumExtensions.GetValues<OrderStatus>())
    Console.WriteLine(status);

Exceptions (AboExtensions.Exceptions)

using AboExtensions.Exceptions;

GetRootCause - walks the InnerException chain and returns the deepest exception:

new Exception("outer", new Exception("mid", new Exception("root")))
    .GetRootCause().Message    // → "root"

new Exception("no inner").GetRootCause().Message    // → "no inner"

Flatten - returns all exceptions in the chain as a flat sequence, outermost first:

new Exception("a", new Exception("b", new Exception("c")))
    .Flatten()
    .Select(e => e.Message)    // → ["a", "b", "c"]

Guids (AboExtensions.Guids)

using AboExtensions.Guids;

IsEmpty / IsNotEmpty - checks against Guid.Empty:

Guid.Empty.IsEmpty()       // → true
Guid.NewGuid().IsEmpty()   // → false

OrNew - returns the Guid if not empty, otherwise generates a new one:

Guid.Empty.OrNew()       // → new Guid
Guid.NewGuid().OrNew()   // → same Guid (unchanged)

IP Addresses (AboExtensions.IpAddresses)

using AboExtensions.IpAddresses;

IsValidIp - true if the string is a valid IPv4 or IPv6 address:

"192.168.1.1".IsValidIp()    // → true
"::1".IsValidIp()            // → true  (IPv6 loopback)
"256.0.0.1".IsValidIp()      // → false
"hello".IsValidIp()          // → false

IsValidIpV4 / IsValidIpV6 - version-specific validation:

"192.168.1.1".IsValidIpV4()   // → true
"::1".IsValidIpV4()           // → false
"::1".IsValidIpV6()           // → true
"192.168.1.1".IsValidIpV6()   // → false

ToIpAddress - parses to IPAddress?, returning null if invalid:

"192.168.1.1".ToIpAddress()   // → IPAddress { 192.168.1.1 }
"invalid".ToIpAddress()       // → null

Nullables (AboExtensions.Nullables)

using AboExtensions.Nullables;

IfNotNull - executes an action only if the value is not null, works for both reference types and nullable value types:

string? name = "Mario";
name.IfNotNull(n => Console.WriteLine(n));   // prints "Mario"

string? empty = null;
empty.IfNotNull(n => Console.WriteLine(n));  // does nothing

int? score = 42;
score.IfNotNull(s => Console.WriteLine(s));  // prints "42"

MapNotNull - transforms a nullable value with a function, returning default if null:

string? s = "hello";
s.MapNotNull(x => x.Length)      // → 5
s.MapNotNull(x => x.ToUpper())   // → "HELLO"

string? n = null;
n.MapNotNull(x => x.Length)      // → 0 (default int)
n.MapNotNull(x => x.ToUpper())   // → null

// chaining:
"42".MapNotNull(int.Parse).MapNotNull(n => n * 2)   // → 84

Objects (AboExtensions.Objects)

using AboExtensions.Objects;

IsNull / IsNotNull - readable null checks on any object:

((string?)null).IsNull()     // → true
"hello".IsNull()             // → false
"hello".IsNotNull()          // → true

Also - executes a side-effect on the object and returns it unchanged, for use inside fluent pipelines:

user.Also(u => { logger.Log(u.Name); return true; })
    .Save();

// chaining:
"hello"
    .Also(s => { log.Add(s); return true; })
    .Also(s => { log.Add(s.ToUpper()); return true; });
// log → ["hello", "HELLO"], result → "hello"

Let - applies a transformation and returns the result; readable alternative to a temporary variable:

"42".Let(int.Parse)              // → 42
"hello".Let(s => s.Length)       // → 5
5.Let(n => n.ToString())         // → "5"

// chaining:
"42".Let(int.Parse).Let(n => n * 2)   // → 84

In / NotIn - checks whether a value is (or isn't) in a set of candidates; readable alternative to chained ||:

status.In(Active, Pending)          // → true if status is either
"x".In("a", "b", "c")              // → false
status.NotIn(Deleted, Archived)     // → true if status is neither

Randoms (AboExtensions.Randoms)

using AboExtensions.Randoms;

NextBool - returns true or false with 50/50 probability, or with a given probability:

rng.NextBool()          // → true or false (50%)
rng.NextBool(0.9)       // → true ~90% of the time
rng.NextBool(1.0)       // → always true
rng.NextBool(0.0)       // → always false

NextItem - returns a random element from a list:

rng.NextItem(new[] { "a", "b", "c" })   // → "a", "b" or "c"

RandomItem - extension on IList<T>, picks a random element without needing a Random instance:

new[] { 1, 2, 3 }.RandomItem()   // → 1, 2 or 3

NextEnum - returns a random value of an enum:

rng.NextEnum<DayOfWeek>()   // → one of the 7 days

NextString - generates a random string of the given length from a character pool:

rng.NextString(8)                   // → e.g. "k4f2m9xr"  (alphanumeric + - _)
rng.NextString(4, "AEIOU")          // → e.g. "OEUA"

Reflection (AboExtensions.Reflections)

using AboExtensions.Reflections;

GetPropertyByName - reads a property value by name:

var person = new { Name = "Mario", Age = 30 };
person.GetPropertyByName("Name")    // → "Mario"
person.GetPropertyByName("Age")     // → 30

GetPropertiesToString - concatenates multiple property values into a string:

var person = new { FirstName = "Mario", LastName = "Rossi" };
ReflectionExtensions.GetPropertiesToString(person, "FirstName,LastName")              // → "Mario Rossi"
ReflectionExtensions.GetPropertiesToString(person, "FirstName,LastName", outSep: '-') // → "Mario-Rossi"
ReflectionExtensions.GetPropertiesToString(person, "FirstName;LastName", inSep: ';')  // → "Mario Rossi"

StringBuilders (AboExtensions.StringBuilders)

using AboExtensions.StringBuilders;

AppendIf - appends text only if the condition is true; returns the builder for chaining:

new StringBuilder()
    .AppendIf(true, "hello")
    .AppendIf(false, " world")
    .ToString()    // → "hello"

AppendLineIf - like AppendIf but also appends a newline:

new StringBuilder()
    .AppendLineIf(true, "line1")
    .AppendLineIf(false, "line2")
    .ToString()    // → "line1\r\n"

Prepend - inserts text at the beginning of the builder:

new StringBuilder("world").Prepend("hello ").ToString()   // → "hello world"

TimeSpans (AboExtensions.TimeSpans)

using AboExtensions.TimeSpans;

IsZero - true if the TimeSpan equals TimeSpan.Zero:

TimeSpan.Zero.IsZero()              // → true
TimeSpan.FromSeconds(1).IsZero()    // → false

Ago / FromNow - converts a TimeSpan to a DateTime relative to now:

TimeSpan.FromHours(2).Ago()       // → DateTime.Now - 2 hours
TimeSpan.FromDays(1).FromNow()    // → DateTime.Now + 1 day

Requirements

  • .NET 8.0+

License

MIT

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 was computed.  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.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 101 6/10/2026
0.0.6 111 6/8/2026