See More

A very common reason is a wrong site baseUrl configuration.\n

Current configured baseUrl = / (default value)\n

We suggest trying baseUrl = \n\n',document.body.prepend(n);var e=document.getElementById("__docusaurus-base-url-issue-banner-suggestion-container"),s=window.location.pathname,o="/"===s.substr(-1)?s:s+"/";e.textContent=o}document.addEventListener("DOMContentLoaded",function(){void 0===window.docusaurus&&insertBanner()})

Skip to main content

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

PageDescription
Why this library?The problem with CFE, why not just use record
InstallationNuGet install, requirements
Getting StartedStep-by-step quickstart with core concepts
Attribute Reference[ValueObject], [EqualityMember], [IgnoreEqualityMember]
Member SelectionHow properties are chosen for equality
What Gets GeneratedExact code the generator emits
Struct vs. ClassWhen to use each, ForceClass
Nullable PropertiesNull-safe comparison generation
Usage PatternsDictionary keys, HashSets, LINQ, EF Core, pattern matching
Migration GuideFrom CFE ValueObject, from manual equality
PerformanceBenchmark results and how to run them
Design & LimitationsTrade-offs, things not generated
TroubleshootingCommon errors and fixes
TestingTesting value objects — equality, hash codes, serialization
Examples
E-CommerceProductId, Money, ShippingAddress, Discount
FinanceIban, CurrencyPair, AccountNumber
HR / IdentityEmailAddress, EmployeeId, FullName
GeospatialCoordinates, GeoRegion
SchedulingDateRange, 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.