FclEx.Core 2.4.8

dotnet add package FclEx.Core --version 2.4.8
                    
NuGet\Install-Package FclEx.Core -Version 2.4.8
                    
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="FclEx.Core" Version="2.4.8" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FclEx.Core" Version="2.4.8" />
                    
Directory.Packages.props
<PackageReference Include="FclEx.Core" />
                    
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 FclEx.Core --version 2.4.8
                    
#r "nuget: FclEx.Core, 2.4.8"
                    
#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 FclEx.Core@2.4.8
                    
#: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=FclEx.Core&version=2.4.8
                    
Install as a Cake Addin
#tool nuget:?package=FclEx.Core&version=2.4.8
                    
Install as a Cake Tool

FclEx.Core

The foundational package for FclEx.

What Is Included

  • Extension methods for common .NET types, including strings, collections, LINQ, reflection, IO, networking, JSON, XML, tasks, diagnostics, and random test-data generation.
  • OperationResult and related helpers for success, failure, exceptions, elapsed time, and input/output tracking.
  • IAction<T> pipelines for composing, mapping, retrying, and combining operations.
  • Domain entity contracts such as IHasId<T>, soft-delete interfaces, common entity base types, entity data comparers, and entity change helpers.
  • Collection implementations such as BiDictionary, BPlusTreeDictionary, Deque, Heap, ordered lists, ordered indexes, and multi-value dictionaries.
  • Comparers and comparer builders, including key/member comparers, delegate comparers, enumerable comparers, bitwise and interop-marshal equality comparers, and equality-comparer builders.
  • Serialization helpers for System.Text.Json and XML.
  • Utility types for disposables, lazy values, paging, console tables, regexes, runtime checks, expression building, and source building.
  • Combinatorics collections for combinations, permutations, and variations.

Usage Notes

  • This package is intentionally broad and is referenced by most other FclEx packages.
  • Prefer using focused extension methods and small utility types directly rather than treating the package as an application framework.
  • Several APIs backfill newer .NET conveniences on older target frameworks.

Concurrent file transfers

The CopyToAsync and MoveTo overloads that accept FileTransferOptions coordinate non-overwriting transfers by candidate destination path within the process. Copies and moves share the same locks, including when auto-renaming reaches a path requested directly by another transfer. Different paths in the same directory can proceed independently. Copying to a temporary file happens outside the destination lock. Copies wait asynchronously for the destination lock and can cancel that wait; moves wait synchronously. Both use the same per-path AsyncLock.

Path matching follows the package's operating-system convention: case-insensitive on Windows and case-sensitive elsewhere. Other processes, symbolic-link aliases, and explicit overwrite operations are outside this coordination.

Entity data equality

Use EntityDataEqualityComparer to compare entity data when deciding whether an update is needed. This compares public readable instance fields and non-indexer properties of the declared type, including inherited members. It compares data rather than identity alone: the primary key and other included members all participate.

using FclEx.Domain;

var comparer = EntityDataEqualityComparer.Create<Customer>();
var needsUpdate = !comparer.Equals(existing, incoming);

// A complete replacement for the default exclusion list.
var customComparer = EntityDataEqualityComparer.Create<Customer>(["Version"]);

public class Customer
{
    public long Id { get; set; }
    public string? Name { get; set; }
    public DateTimeOffset UpdatedAt { get; set; }
    public int Version { get; set; }

    [EntityDataEqualityIgnore]
    public List<string>? Tags { get; set; }
}

A null exclusion list uses the default names CreatedAt, UpdatedAt, and DeletedAt. A non-null list replaces those defaults entirely; an empty list excludes no members by name. Names are case-sensitive and unknown names are ignored. The ignore attribute always applies, including with an empty list. An inherited member keeps its attribute; an overriding property must be marked again.

Comparison is shallow and uses each member's default equality comparer. Collections and navigation properties may therefore compare by reference; ignore them or construct a separate comparer when different rules are needed. Members declared only by runtime subtypes are not inspected, and different runtime types compare unequal. Null compares equal only to null. Hash codes use the included members as well.

EntityDataEqualityComparer<T>.Instance is cached. Null exclusions, or exclusions set-equal to the fixed defaults, return that instance. The default names cannot be modified. Pass a complete exclusion list to Create to use a different policy. Custom comparers fix their member selection at creation and do not track changes to the supplied list.

Adjacent duplicate removal

Use DistinctAdjacent to retain the first element of each consecutive run of equal elements, or DistinctAdjacentBy to compare keys while returning the original elements. Unlike LINQ's Distinct / DistinctBy, these methods retain equal values or keys when they are separated by a different value or key, and preserve source order.

using FclEx.Extensions;

new[] { 1, 1, 2, 2, 2, 1 }.DistinctAdjacent(); // [1, 2, 1]
new[] { "one", "two", "four", "five", "six" }
    .DistinctAdjacentBy(item => item.Length); // ["one", "four", "six"]
new[] { "a", "A", "b", "a" }
    .DistinctAdjacent(StringComparer.OrdinalIgnoreCase); // ["a", "b", "a"]

Both methods validate required arguments immediately, but enumerate lazily using constant additional space. Each enumeration makes one pass over the source; DistinctAdjacentBy selects a key exactly once per visited element. An omitted or null comparer uses the default equality comparer for the element or key type.

Adjacent run counting

CountAdjacent returns (Item, Count) for each consecutive run of equal elements, retaining the first original element. CountAdjacentBy selects keys and returns (Key, Count) for each consecutive run of equal keys, retaining the first selected key. Equal values or keys separated by a different value or key are counted separately.

new[] { 1, 1, 2, 2, 2, 1 }.CountAdjacent(); // [(1, 2), (2, 3), (1, 1)]
new[] { "one", "two", "four", "five", "six" }
    .CountAdjacentBy(item => item.Length); // [(3, 2), (4, 2), (3, 1)]

These methods validate required arguments immediately and enumerate lazily in one pass using constant additional space. Each run is yielded only after its end is found, so enumeration reads the first element of the next run before returning the current run. Key selection occurs once per visited element. A run exceeding int.MaxValue throws OverflowException; an unbounded equal run cannot yield a completed result. Omitted or null comparers use the default element or key equality comparer.

String delimiters

Use IsSquareBracketed / TrimSquareBrackets, IsParenthesized / TrimParentheses, IsCurlyBracketed / TrimCurlyBrackets, and IsAngleBracketed / TrimAngleBrackets for brackets. Quotes use IsDoubleQuoted / TrimDoubleQuotes, IsSingleQuoted / TrimSingleQuotes, and IsBacktickQuoted / TrimBackticks. Slash pairs use IsSlashDelimited / TrimSlashes and IsBackslashDelimited / TrimBackslashes.

These methods require a non-null string and check only its first and last characters. Trimming removes exactly one matching outer pair, preserves inner content and whitespace, and returns the original string when no matching pair is present. A bare pair encloses an empty string. Nesting and escape sequences are not parsed.

"(value)".IsParenthesized();     // true
"((value))".TrimParentheses();   // "(value)"
"/value/".TrimSlashes();         // "value"
" value ".TrimDoubleQuotes();   // " value "

Use the corresponding WrapWith... methods to add a new pair: WrapWithSquareBrackets, WrapWithParentheses, WrapWithCurlyBrackets, WrapWithAngleBrackets, WrapWithDoubleQuotes, WrapWithSingleQuotes, WrapWithBackticks, WrapWithSlashes, and WrapWithBackslashes. These methods always add a pair, preserve content without escaping it, and reject null with ArgumentNullException. Empty strings produce a bare pair.

"value".WrapWithParentheses();   // "(value)"
"(value)".WrapWithParentheses(); // "((value))"
"".WrapWithSquareBrackets();    // "[]"

For custom delimiters, use IsWrappedWith, WrapWith, TrimWrapper, and EnsureWrappedWith. Each has string and char overloads. Omitting close (or passing null) uses open on both ends; closing brackets are not inferred. String delimiters must be non-null and non-empty and are matched using StringComparison.Ordinal. Matching requires both complete delimiters without overlap.

EnsureWrappedWith returns the original string if it already has the specified outer pair; otherwise, it adds one pair. The same behavior is available through EnsureSquareBracketed, EnsureParenthesized, EnsureCurlyBracketed, EnsureAngleBracketed, EnsureDoubleQuoted, EnsureSingleQuoted, EnsureBacktickQuoted, EnsureSlashDelimited, and EnsureBackslashDelimited.

"value".WrapWith("/*", "*/");              // "/*value*/"
"/*/".IsWrappedWith("/*", "*/");           // false: overlapping delimiters
"/**/".TrimWrapper("/*", "*/");            // ""
"value".EnsureWrappedWith('(', ')');        // "(value)"
"(value)".EnsureParenthesized();   // "(value)"

All methods in this family reject a null source with ArgumentNullException, including the existing specific check and trim methods, which previously threw NullReferenceException. The string overloads reject a null open with ArgumentNullException and empty delimiters with ArgumentException. The existing specific methods delegate to these general methods.

Runtime storage helpers

FieldInfos and PropertyInfos.JsonTypeInfoResolver.Empty cache descriptors for runtime internals. UnsafeAccessors exposes writable field references on .NET 8 and later. These APIs bypass validation, may invalidate cached state, and depend on the exact runtime field layout. Prefer the focused extension methods when direct mutation is unnecessary. IPAddress.AddressNumbers() exposes IPv6 segments; IPv4 returns an empty view on modern .NET and eight zero segments on .NET Framework. The netstandard2.0 reflection path throws if the running runtime stores a null IPv4 segment array.

The descriptor entries in FieldInfos are now lazy properties instead of static readonly fields; recompile consumers when upgrading. Replace PropertyInfos.JsonTypeInfoResolver_Empty with PropertyInfos.JsonTypeInfoResolver.Empty. The named parameter for SetStackTrace is now stackTrace.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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 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.  net11.0 is compatible. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 is compatible.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (5)

Showing the top 5 NuGet packages that depend on FclEx.Core:

Package Downloads
FclEx.YamlDotNet

YamlDotNet helpers, options, converters, naming conventions, and YAML node extensions.

FclEx.DependencyInjection

Convenience extensions for service registration, replacement, removal, decoration, scopes, and provider lookup.

FclEx.EfCore

Entity Framework Core query, update, soft-delete, schema, table truncation, identity-sequence synchronization, service-registration, SSH tunnel, and test-model helpers.

FclEx.Dapper

Focused Dapper extensions for cached CRUD SQL, bounded multi-row inserts, local transactions, table existence checks, truncation and identity synchronization, explicit entity mappings, and provider-specific SQL adapters.

FclEx.NewtonsoftJson

Newtonsoft.Json converters and helpers for flexible JSON parsing, serialization, JToken, and XML conversion.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.4.8 74 11/13/2026
2.4.7 176 11/12/2026
2.4.6 186 11/12/2026
2.4.5 196 11/12/2026
2.4.4 735 11/5/2026
2.4.3 738 11/1/2026
2.4.2 727 10/10/2026
2.4.1 685 10/8/2026
2.4.0 715 10/3/2026
2.3.9 687 9/27/2026
2.3.8 682 9/26/2026
2.3.7 671 9/24/2026
2.3.6 691 9/22/2026
2.3.5 687 9/22/2026
2.3.4 727 8/28/2026
2.3.3 755 8/22/2026
2.3.2 735 8/20/2026
2.3.1 758 8/19/2026
2.3.0 759 8/17/2026
2.2.9 931 7/18/2026
Loading failed