ZeroAlloc.ValueObjects
2.2.2
dotnet add package ZeroAlloc.ValueObjects --version 2.2.2
NuGet\Install-Package ZeroAlloc.ValueObjects -Version 2.2.2
<PackageReference Include="ZeroAlloc.ValueObjects" Version="2.2.2" />
<PackageVersion Include="ZeroAlloc.ValueObjects" Version="2.2.2" />
<PackageReference Include="ZeroAlloc.ValueObjects" />
paket add ZeroAlloc.ValueObjects --version 2.2.2
#r "nuget: ZeroAlloc.ValueObjects, 2.2.2"
#:package ZeroAlloc.ValueObjects@2.2.2
#addin nuget:?package=ZeroAlloc.ValueObjects&version=2.2.2
#tool nuget:?package=ZeroAlloc.ValueObjects&version=2.2.2
ZeroAlloc.ValueObjects
Source-generated value objects and strongly-typed IDs for .NET: record-speed equality on the classes and structs you already have, with no allocation and no base class, NativeAOT-ready.
Why ZeroAlloc.ValueObjects
- Equality allocates nothing.
Equals,GetHashCode,==and!=allocate 0 B on a class and on a struct, asserted by tests. CSharpFunctionalExtensions'ValueObjectallocates 96 B perEqualsin the same benchmark. - As fast as
record, without rewriting your types to records. Equality on a two-field value object runs in the same time asrecordand 14.6× faster than CSharpFunctionalExtensions. Equality on a single-intvalue object is 13× faster than Vogen's. - Works under NativeAOT and trimming. No reflection in generated code, including the EF Core converter registration. A NativeAOT smoke app is published and run in CI.
- Mistakes fail the build. An ID strategy that does not fit its backing type, such as Snowflake on a
Guid, is compile error ZATI001.
Install
dotnet add package ZeroAlloc.ValueObjects
Quick start
using ZeroAlloc.ValueObjects;
var price = new Money(10m, "EUR");
var prices = new HashSet<Money> { price, new Money(10m, "EUR") };
Console.WriteLine(price == new Money(10m, "EUR")); // True: compared by value, 0 B
Console.WriteLine(prices.Count); // 1: safe as a set or dictionary key
OrderId id = OrderId.New(); // sortable ULID
Console.WriteLine($"{id} {OrderId.Parse(id.ToString()) == id}");
[ValueObject]
public partial class Money
{
public decimal Amount { get; }
public string Currency { get; }
public Money(decimal amount, string currency) => (Amount, Currency) = (amount, currency);
}
[TypedId(Strategy = IdStrategy.Ulid)]
public readonly partial record struct OrderId;
Money keeps its constructor, its base class and its shape. The generator adds the equality members and a ToString, without the with, Deconstruct and EqualityContract a record brings.
What you get
- Value objects on existing types:
[ValueObject]on anypartial classorpartial struct, including classes that inherit from a non-record base. - Member control: opt members in with
[EqualityMember]or out with[IgnoreEqualityMember]. Nullable reference properties compare null-safely. - Strongly-typed IDs:
[TypedId]with ULID, UUIDv7, Snowflake and Sequential strategies, plus an assembly-wide default. - JSON through a generated
System.Text.Jsonconverter that reads and writes with 0 B allocated, asserted by tests. - ASP.NET Core binding: IDs implement
IParsable<T>andISpanParsable<T>, so(OrderId id) => …route parameters just work. - EF Core: ZeroAlloc.ValueObjects.EfCore maps every typed ID in an assembly with one generated, trim-safe call.
- Snowflake worker IDs from a number, an environment variable or a factory. ZeroAlloc.ValueObjects.Hosting adds a factory that resolves services.
- Serialisation: ZeroAlloc.Serialisation writes single-value objects as their underlying value in JSON, MessagePack and MemoryPack.
Performance
BenchmarkDotNet. Allocations are exact. The time column is the alternative's time divided by ZeroAlloc.ValueObjects', from the same run.
| Operation | ZeroAlloc.ValueObjects | Alternative | Alternative's time |
|---|---|---|---|
Equals, two-field Money |
0 B | CSharpFunctionalExtensions, 96 B | 14.6× |
GetHashCode, two-field Money |
0 B | CSharpFunctionalExtensions, 88 B | 16.1× |
Equals, single-int value object |
0 B | Vogen, 0 B | 13× |
record and record struct allocate 0 B and run in the same time as ZeroAlloc.ValueObjects on the two-field rows. The performance page has every row, including GetHashCode, where Vogen ties, and the typed-ID benchmarks cover generation and parsing per strategy.
Learn more
- Documentation: valueobjects.zeroalloc.net. Good starting points: why not just use
record, typed IDs, the production checklist for IDs and the diagnostics reference for value objects and typed IDs. - Moving from CSharpFunctionalExtensions or hand-written equality: migration guide. Release history: CHANGELOG.md.
- Related packages: ZeroAlloc.Mapping, ZeroAlloc.Results, ZeroAlloc.Serialisation.
- Issues and pull requests are welcome on GitHub.
- MIT licensed. See LICENSE.
| Product | Versions 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 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. |
| .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 is compatible. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. 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. |
-
.NETStandard 2.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.12)
- System.Memory (>= 4.6.3)
- System.Security.Cryptography.Algorithms (>= 4.3.1)
-
.NETStandard 2.1
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.12)
- System.Memory (>= 4.6.3)
- System.Security.Cryptography.Algorithms (>= 4.3.1)
- ZeroAlloc.Serialisation (>= 2.4.2)
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.12)
- System.Memory (>= 4.6.3)
- System.Security.Cryptography.Algorithms (>= 4.3.1)
- ZeroAlloc.Serialisation (>= 2.4.2)
NuGet packages (18)
Showing the top 5 NuGet packages that depend on ZeroAlloc.ValueObjects:
| Package | Downloads |
|---|---|
|
ZeroAlloc.Scheduling
Source-generated zero-allocation background job scheduling for .NET. |
|
|
ZeroAlloc.Outbox
Source-generated transactional outbox for .NET. |
|
|
ZeroAlloc.ValueObjects.EfCore
EF Core value converters and conventions for ZeroAlloc.ValueObjects [TypedId] structs. |
|
|
AI.Sentinel
Security monitoring middleware for IChatClient — prompt injection, hallucination, and operational anomaly detection with an intervention engine. |
|
|
Thalos.NET.Abstractions
Ports and models for Thalos.NET. Depends only on ZeroAlloc primitives and Microsoft.Extensions.AI.Abstractions. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.2.2 | 4,705 | 10/16/2026 |
| 2.2.1 | 2,191 | 10/15/2026 |
| 2.2.0 | 5,458 | 10/12/2026 |
| 2.1.1 | 5,283 | 10/11/2026 |
| 2.1.0 | 6,597 | 10/10/2026 |
| 2.0.12 | 11,772 | 9/30/2026 |
| 2.0.11 | 6,936 | 9/28/2026 |
| 2.0.10 | 6,726 | 9/26/2026 |
| 2.0.9 | 10,929 | 9/21/2026 |
| 2.0.8 | 731 | 9/20/2026 |
| 2.0.7 | 2,467 | 9/20/2026 |
| 2.0.6 | 6,025 | 9/19/2026 |
| 2.0.5 | 6,759 | 8/10/2026 |
| 2.0.4 | 277 | 8/9/2026 |
| 2.0.3 | 1,358 | 8/8/2026 |
| 2.0.2 | 476 | 8/7/2026 |
| 2.0.0 | 181 | 8/7/2026 |
| 1.7.2 | 1,688 | 8/6/2026 |
| 1.7.1 | 3,334 | 6/11/2026 |
| 1.7.0 | 2,549 | 5/18/2026 |