Skip to content

feat(serialization): add codecs for FrozenDictionary and FrozenSet - #10270

Merged
ReubenBond merged 2 commits into
mainfrom
reubenbond-frozen-collection-codecs
Jul 16, 2026
Merged

ReubenBond merged 2 commits into
mainfrom
reubenbond-frozen-collection-codecs

Conversation

@ReubenBond

@ReubenBond ReubenBond commented Jul 15, 2026 •

Copy link
Copy Markdown
Member

Problem

Orleans had no serialization support for the frozen collection types introduced in .NET 8 (FrozenDictionary<TKey, TValue> and FrozenSet<T>). Attempting to serialize a grain call, storage payload, or stream event containing one of these types would fail.

Solution

Add serialization codecs and copiers for FrozenDictionary<TKey, TValue> and FrozenSet<T>, modeled on the existing immutable-collection codecs. They are guarded by #if NET8_0_OR_GREATER so they only compile on platforms that ship the frozen collections (the netstandard2.1 target excludes them).

Notable details:

  • Surrogates carry the entries as a List<> plus the collection's comparer (stored only when non-default). Reading entries straight out of the source collection avoids re-hashing keys when constructing the surrogate.
  • Copiers deep-copy their contents in the same manner as the immutable-collection copiers, short-circuiting to a shallow copy when the element copiers are shallow-copyable.
  • Frozen collection types are abstract base types whose runtime instances are internal subtypes, potentially of a different generic arity. The copiers therefore implement IDerivedTypeCopier, and CodecProvider.CreateCopierInstance now advances the field type and search type in lockstep when resolving derived-type copiers, mirroring the existing codec-side logic. Without this, resolving a copier for a subtype with mismatched arity threw an ArgumentException from MakeGenericType.

Tests cover round-tripping through the codec, copier behavior (including mutable element types), and comparer preservation.

Microsoft Reviewers: Open in CodeFlow

Add Orleans serialization codecs and copiers for the .NET 8 frozen collection types FrozenDictionary<TKey, TValue> and FrozenSet<T>, guarded by NET8_0_OR_GREATER so they only compile on supporting platforms.

The copiers deep-copy contents in the same manner as the immutable collection copiers, short-circuiting to a shallow copy when the element copiers are shallow-copyable. Because the frozen collection types are abstract base types whose runtime instances are internal subtypes (potentially of different generic arity), the copiers implement IDerivedTypeCopier and CodecProvider.CreateCopierInstance now advances the field type and search type in lockstep when resolving derived-type copiers, mirroring the existing codec-side logic.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 564fb626-a0b7-4860-97fd-3e00d83d60dc
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds built-in Orleans.Serialization support for .NET 8 frozen collections so FrozenDictionary<TKey, TValue> and FrozenSet<T> can be serialized/copied in grain calls, storage payloads, and stream events on NET8+.

Changes:

  • Add new codecs, surrogates, and deep copiers for FrozenDictionary<TKey, TValue> and FrozenSet<T> (NET8+ only).
  • Update copier resolution in CodecProvider to correctly handle derived types whose generic arity differs from their base type (needed for frozen collections’ internal runtime types).
  • Add unit tests covering round-trip serialization and copier behavior, including comparer preservation.
Show a summary per file
File Description
test/Orleans.Serialization.UnitTests/BuiltInCodecTests.cs Adds codec and copier tests for frozen collections and validates comparer preservation.
src/Orleans.Serialization/Serializers/CodecProvider.cs Fixes derived-type copier lookup to advance field/search types together when walking base types.
src/Orleans.Serialization/Codecs/FrozenSetCodec.cs Introduces NET8+ codec/surrogate/copier for FrozenSet<T>.
src/Orleans.Serialization/Codecs/FrozenDictionaryCodec.cs Introduces NET8+ codec/surrogate/copier for FrozenDictionary<TKey, TValue>.

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 2

Comment thread src/Orleans.Serialization/Codecs/FrozenSetCodec.cs
Comment thread src/Orleans.Serialization/Codecs/FrozenDictionaryCodec.cs
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 564fb626-a0b7-4860-97fd-3e00d83d60dc
@ReubenBond
ReubenBond merged commit 9f859cd into main Jul 16, 2026
120 of 121 checks passed
@ReubenBond
ReubenBond deleted the reubenbond-frozen-collection-codecs branch July 16, 2026 20:38
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants