ZeroAlloc.Results
1.2.0
dotnet add package ZeroAlloc.Results --version 1.2.0
NuGet\Install-Package ZeroAlloc.Results -Version 1.2.0
<PackageReference Include="ZeroAlloc.Results" Version="1.2.0" />
<PackageVersion Include="ZeroAlloc.Results" Version="1.2.0" />
<PackageReference Include="ZeroAlloc.Results" />
paket add ZeroAlloc.Results --version 1.2.0
#r "nuget: ZeroAlloc.Results, 1.2.0"
#:package ZeroAlloc.Results@1.2.0
#addin nuget:?package=ZeroAlloc.Results&version=1.2.0
#tool nuget:?package=ZeroAlloc.Results&version=1.2.0
ZeroAlloc.Results
ZeroAlloc.Results is a zero-allocation, no-boxing Result<T, E> library for .NET 9. All types are readonly struct — no heap allocation, no boxing, no GC pressure.
Install
dotnet add package ZeroAlloc.Results
Quick Example
using ZeroAlloc.Results;
using ZeroAlloc.Results.Extensions;
// Create
Result<int, string> ok = Result<int, string>.Success(42);
Result<int, string> fail = Result<int, string>.Failure("not found");
// Or via implicit conversion
Result<int, string> r = 42; // success
Result<int, string> e = "error"; // failure
// Chain with Map, Bind, Ensure
var result = GetUser(id)
.Ensure(u => u.IsActive, "user is inactive")
.Map(u => u.Email)
.Bind(email => SendWelcome(email));
// Match to extract
string message = result.Match(
onSuccess: email => $"Sent to {email}",
onFailure: err => $"Failed: {err}");
// LINQ query syntax
var greeting =
from user in GetUser(id)
from profile in GetProfile(user)
select $"Hello, {profile.Name}";
// Async pipelines with ValueTask
var response = await GetUser(id)
.MapAsync(async u => await LoadPermissions(u))
.BindAsync(async p => await BuildToken(p));
Types
| Type | Success | Error | Use case |
|---|---|---|---|
Result |
— | string |
simple pass/fail |
Result<T> |
T |
string |
most common |
Result<T, E> |
T |
E |
fully generic |
UnitResult<E> |
— | E |
typed error, no value |
Maybe<T> |
T |
— | optional value |
API
| Method | Description |
|---|---|
Map(T→U) |
Transform the success value |
MapError(E→F) |
Transform the error value |
Bind(T→Result<U,E>) |
Chain result-returning functions |
Match(onSuccess, onFailure) |
Extract a value from either branch |
Tap(T→void) |
Side-effect on success, pass through |
TapError(E→void) |
Side-effect on failure, pass through |
Ensure(T→bool, E) |
Validate success value |
Combine(Span<Result<T,E>>) |
Merge multiple results, zero-alloc |
*Async |
ValueTask-based variant of each combinator |
Performance
ZeroAlloc.Results is the only result library in .NET with 0 B allocation on every path — including failure construction. .NET 10.0.7, i9-12900HK, BenchmarkDotNet v0.15.4.
| Scenario | ZeroAlloc.Results | OneOf | ErrorOr | FluentResults |
|---|---|---|---|---|
| Success construct | 0.4 ns / 0 B | 0.5 ns / 0 B | 0.0 ns / 0 B | 87 ns / 112 B |
| Failure construct | 0.3 ns / 0 B | 0.9 ns / 0 B | 63 ns / 184 B | 87 ns / 272 B |
| Failure consume | 0.4 ns / 0 B | 0.9 ns / 0 B | 2.6 ns / 0 B | 214 ns / 240 B |
| Hot loop (100 iter, 1-in-3 fail) | 183 ns / 0 B | 202 ns / 0 B | 7,693 ns / 6,256 B | 39,450 ns / 25,968 B |
On the realistic mixed-success/failure workload, ZeroAlloc.Results is 1.1× faster than OneOf, 42× faster than ErrorOr, and 216× faster than FluentResults — with zero allocation while the latter two allocate per-failure.
Head-to-head vs CSharpFunctionalExtensions: 1.1–8.7× faster depending on operation; 0 B both.
See docs/performance.md for full methodology, all scenarios, and analysis.
Documentation
| Page | Description |
|---|---|
| Getting Started | Install and write your first result pipeline |
| Types | All five result types and when to use each |
| Combinators | Map, Bind, Match, Tap, Ensure, Combine |
| Async | ValueTask async variants for all combinators |
| LINQ | Query syntax with Select and SelectMany |
| Performance | Zero-alloc design and benchmark results |
License
MIT
| Product | Versions 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 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.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (9)
Showing the top 5 NuGet packages that depend on ZeroAlloc.Results:
| Package | Downloads |
|---|---|
|
ZeroAlloc.Resilience
Source-generated, zero-allocation resilience policies for .NET. Add [Retry], [Timeout], [RateLimit], and [CircuitBreaker] to an interface; the generator emits a proxy composing all policies in declaration order. AOT-safe. |
|
|
ZeroAlloc.Rest
Source-generated, AOT-compatible REST client for .NET |
|
|
ZeroAlloc.Authorization
Authorization primitives for .NET — ISecurityContext, IAuthorizationPolicy, [Policy] / [RequirePolicy] attributes with a source generator that emits DI registrations and per-request AuthorizerFor<T> dispatchers. Shared by AI.Sentinel and ZeroAlloc.Mediator.Authorization. |
|
|
AI.Sentinel
Security monitoring middleware for IChatClient — prompt injection, hallucination, and operational anomaly detection with an intervention engine. |
|
|
ZeroAlloc.Mapping
Source-generated, zero-allocation Command→Domain→DTO mapper for .NET. [Map<,>]/[TryMap<,>] on a static partial class — generator emits direct property assignments at compile time. Result<T, MappingError> on the [TryMap] path; ValueObjects smart constructors honoured automatically. AOT-safe. |
GitHub repositories
This package is not used by any popular GitHub repositories.