VelvetCraft.Dotnet.Core
1.1.1
dotnet add package VelvetCraft.Dotnet.Core --version 1.1.1
NuGet\Install-Package VelvetCraft.Dotnet.Core -Version 1.1.1
<PackageReference Include="VelvetCraft.Dotnet.Core" Version="1.1.1" />
<PackageVersion Include="VelvetCraft.Dotnet.Core" Version="1.1.1" />
<PackageReference Include="VelvetCraft.Dotnet.Core" />
paket add VelvetCraft.Dotnet.Core --version 1.1.1
#r "nuget: VelvetCraft.Dotnet.Core, 1.1.1"
#:package VelvetCraft.Dotnet.Core@1.1.1
#addin nuget:?package=VelvetCraft.Dotnet.Core&version=1.1.1
#tool nuget:?package=VelvetCraft.Dotnet.Core&version=1.1.1
VelvetCraft.Dotnet.Core
Zero-dependency utility helpers for .NET 10: string extensions, collection extensions, DateTime/TimeSpan helpers, enum utilities, guard clauses, and generic comparison/interval helpers.
Installation
dotnet add package VelvetCraft.Dotnet.Core
Features
- String extensions — null/empty checks, case conversion, Base64 encode/decode, GUID validation, sanitization, substring extraction and more
- Collection extensions — null-safe enumeration helpers, predicate checks, safe list mutation utilities
- DateTime extensions — Unix timestamps, ISO 8601 formatting, month/day boundaries, range checks and day iteration
- TimeSpan extensions — time-of-day validation
- Enum extensions — read
[Description]attributes, enumerate members with exclusions - Guard clauses —
Guard.NotNull(),Guard.NotEmpty(),Guard.NotNullOrWhiteSpace()— fail-fast argument validation - ComparableHelper — generic
Min<T>()/Max<T>()for anyIComparable<T> - IntervalHelper — period consistency checks and overlap calculation for
DateTimeranges
String Extensions
Namespace: VelvetCraft.Dotnet.Core.Extensions
using VelvetCraft.Dotnet.Core.Extensions;
// Null / empty checks
"".IsNullOrEmpty(); // true
" ".IsNullOrWhiteSpace(); // true
"hi".IsNullOrEmpty(); // false
// Case conversion
"HelloWorld".ToSnakeCase(); // "hello_world"
"myPropertyName".ToSnakeCase(); // "my_property_name"
"HelloWorld".ToCamelCase(); // "helloWorld"
"hello world".ToTitleCase(); // "Hello World"
// GUID helpers
"550e8400-e29b-41d4-a716-446655440000".IsGuid(); // true
"not-a-guid".ToGuid(); // Guid.Empty
// Base64
"Hello".ToBase64(); // "SGVsbG8="
"SGVsbG8=".IsBase64(); // true
"SGVsbG8=".FromBase64(); // "Hello"
// Sanitize — trims leading/trailing newlines and whitespace, returns null when blank
"\n value \n".Sanitize(); // "value"
" ".Sanitize(); // null
// SubstringBetween — extracts text between two delimiters
"[hello]".SubstringBetween("[", "]"); // "hello"
// Case-insensitive equality
"Hello".EqualsIgnoreCase("hello"); // true
Collection Extensions
Namespace: VelvetCraft.Dotnet.Core.Extensions
using VelvetCraft.Dotnet.Core.Extensions;
List<int>? items = null;
items.IsNullOrEmpty(); // true
items.OrEmpty(); // returns Enumerable.Empty<int>()
var list = new[] { 1, 2, 3 };
list.IsSingle(); // false
list.IsMultiple(); // true
list.HasAny(x => x > 2); // true
// EqualsAny — checks whether a value is contained in a set of candidates
Status.Active.EqualsAny(Status.Active, Status.Pending); // true
// Safe list mutation
var result = new List<string?>();
result.AddIfNotNull(null); // no-op
result.AddIfNotNull("hello"); // adds "hello"
result.AddRangeIfNotEmpty(null); // no-op
result.AddRangeIfNotEmpty(new[] { "a", "b" }); // adds both
// Order check
new[] { 1, 2, 3 }.IsOrderedBy(x => x); // true
new[] { 3, 1, 2 }.IsOrderedBy(x => x); // false
DateTime Extensions
Namespace: VelvetCraft.Dotnet.Core.Extensions
using VelvetCraft.Dotnet.Core.Extensions;
var dt = new DateTime(2026, 6, 15, 10, 30, 0, DateTimeKind.Utc);
// Unix timestamps (auto-converts non-UTC to UTC)
dt.ToUnixTimestampMs(); // 1781825400000L
dt.ToUnixTimestampSeconds(); // 1781825400
// ISO 8601
dt.ToIsoString(); // "2026-06-15T10:30:00.0000000Z"
// Month boundaries
dt.StartOfMonth(); // 2026-06-01 00:00:00
dt.EndOfMonth(); // 2026-06-30 23:59:59.999
// Day navigation
dt.StartOfNextDay(); // 2026-06-16 00:00:00
// Set time components on an existing date
dt.WithTime(0, 0, 0, 0); // 2026-06-15 00:00:00
// Range check
dt.IsInRange(new DateTime(2026, 1, 1), new DateTime(2026, 12, 31)); // true
// Treat default (MinValue) as null
DateTime.MinValue.ParseOrNull(); // null
dt.ParseOrNull(); // dt
// Iterate each day between two dates
foreach (var day in DateTimeExtensions.EachDay(dt, dt.AddDays(2)))
Console.WriteLine(day); // 2026-06-15, 2026-06-16, 2026-06-17
// Return the later of two values
DateTimeExtensions.Latest(dt, dt.AddHours(1)); // dt + 1 hour
TimeSpan Extensions
Namespace: VelvetCraft.Dotnet.Core.Extensions
using VelvetCraft.Dotnet.Core.Extensions;
TimeSpan.FromHours(12).IsValidTime(); // true — within [00:00, 24:00)
TimeSpan.FromHours(25).IsValidTime(); // false
TimeSpan.FromHours(-1).IsValidTime(); // false
Enum Extensions
Namespace: VelvetCraft.Dotnet.Core.Extensions
using System.ComponentModel;
using VelvetCraft.Dotnet.Core.Extensions;
public enum Status
{
[Description("Active user")] Active,
[Description("Suspended")] Suspended,
Guest
}
Status.Active.GetDescription(); // "Active user"
Status.Guest.GetDescription(); // null (no [Description] attribute)
// Enumerate all members, optionally excluding some
foreach (var s in EnumExtensions.GetValues<Status>())
Console.WriteLine(s); // Active, Suspended, Guest
foreach (var s in EnumExtensions.GetValues<Status>(Status.Guest))
Console.WriteLine(s); // Active, Suspended
Guard Clauses
Namespace: VelvetCraft.Dotnet.Core.Guards
using VelvetCraft.Dotnet.Core.Guards;
public class OrderService
{
private readonly IOrderRepository _repo;
public OrderService(IOrderRepository repo)
{
// Throws ArgumentNullException if null
_repo = Guard.NotNull(repo, nameof(repo));
}
public async Task ProcessAsync(string orderId, string customerId)
{
// Throws ArgumentNullException / ArgumentException if null or empty
orderId = Guard.NotEmpty(orderId, nameof(orderId));
// Throws ArgumentNullException / ArgumentException if null, empty or whitespace
customerId = Guard.NotNullOrWhiteSpace(customerId, nameof(customerId));
await _repo.UpdateAsync(orderId, customerId);
}
}
| Method | Null | Empty | Whitespace-only |
|---|---|---|---|
Guard.NotNull<T>() |
ArgumentNullException |
— | — |
Guard.NotEmpty() |
ArgumentNullException |
ArgumentException |
— |
Guard.NotNullOrWhiteSpace() |
ArgumentNullException |
ArgumentException |
ArgumentException |
ComparableHelper
Namespace: VelvetCraft.Dotnet.Core.Helpers
Generic Min / Max for any type with a default comparer — works with int, decimal, DateTime, string, etc.
using VelvetCraft.Dotnet.Core.Helpers;
ComparableHelper.Min(3, 7); // 3
ComparableHelper.Max("apple", "banana"); // "banana"
var earlier = new DateTime(2026, 1, 1);
var later = new DateTime(2026, 6, 1);
ComparableHelper.Min(earlier, later); // earlier
IntervalHelper
Namespace: VelvetCraft.Dotnet.Core.Helpers
Helpers for DateTime period overlap. Null endpoints are treated as unbounded (open-ended intervals).
using VelvetCraft.Dotnet.Core.Helpers;
var a = new DateTime(2026, 1, 1);
var b = new DateTime(2026, 6, 1);
var c = new DateTime(2026, 4, 1);
var d = new DateTime(2026, 9, 1);
// Consistency check
IntervalHelper.IsPeriodConsistent(a, b); // true (start <= end)
IntervalHelper.IsPeriodConsistent(b, a); // false
IntervalHelper.IsPeriodConsistent(null, b); // true (open start)
// Overlap detection (exclusive on touching boundaries)
IntervalHelper.PeriodsOverlap(a, b, c, d); // true — [Jan→Jun] overlaps [Apr→Sep]
IntervalHelper.PeriodsOverlap(a, b, b, d); // false — touching boundaries do not overlap
// Overlap duration
IntervalHelper.GetOverlapDuration(a, b, c, d);
// TimeSpan of ~61 days (Apr 1 → Jun 1)
Requirements
- .NET 10.0+
License
MIT — see LICENSE
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.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.