ZeroAlloc.ValueObjects — Documentation
Zero-allocation, source-generated value object equality for existing .NET domain types.
Same performance as record — without forcing the record keyword on your domain model.
Contents
| Page | Description |
|---|---|
| Why this library? | The problem with CFE, why not just use record |
| Installation | NuGet install, requirements |
| Getting Started | Step-by-step quickstart with core concepts |
| Attribute Reference | [ValueObject], [EqualityMember], [IgnoreEqualityMember] |
| Member Selection | How properties are chosen for equality |
| What Gets Generated | Exact code the generator emits |
| Struct vs. Class | When to use each, ForceClass |
| Nullable Properties | Null-safe comparison generation |
| Usage Patterns | Dictionary keys, HashSets, LINQ, EF Core, pattern matching |
| Migration Guide | From CFE ValueObject, from manual equality |
| Performance | Benchmark results and how to run them |
| Design & Limitations | Trade-offs, things not generated |
| Troubleshooting | Common errors and fixes |
| Testing | Testing value objects — equality, hash codes, serialization |
| Examples | |
| E-Commerce | ProductId, Money, ShippingAddress, Discount |
| Finance | Iban, CurrencyPair, AccountNumber |
| HR / Identity | EmailAddress, EmployeeId, FullName |
| Geospatial | Coordinates, GeoRegion |
| Scheduling | DateRange, TimeSlot |
Quick Example
using ZeroAlloc.ValueObjects;
[ValueObject]
public partial class Money
{
public decimal Amount { get; }
public string Currency { get; }
public Money(decimal amount, string currency)
{
Amount = amount;
Currency = currency;
}
}
var a = new Money(100m, "USD");
var b = new Money(100m, "USD");
a == b // true
a.GetHashCode() // same as b — safe as dict key
a.ToString() // "Money { Amount = 100, Currency = USD }"
Zero allocations. No record keyword. No base class required.