Skip to content

Major release (1.0.0): .NET 10 only and Position as a value type - #8

Merged
HowardvanRooijen merged 2 commits into
mainfrom
features/net10-major
Jul 23, 2026
Merged

Major release (1.0.0): .NET 10 only and Position as a value type#8
HowardvanRooijen merged 2 commits into
mainfrom
features/net10-major

Conversation

@HowardvanRooijen

Copy link
Copy Markdown
Contributor

Major release (1.0.0) — the breaking follow-up to the modernization PR. Now .NET 10 only, with Position reworked as a value type.

Breaking changes

  • .NET 10 only. The previous release multi-targeted net8.0;net10.0; this drops net8.0. Consumers must be on .NET 10. CI now tests net10.0 only and no longer installs the .NET 8 SDK.
  • Position is now a readonly record struct (value type) instead of a record class. Value-based equality and the Position? usages on the message records are unchanged, but this is a binary-breaking type change.

Performance

Making Position a value type removes a heap allocation per decoded position (measured with BenchmarkDotNet / MemoryDiagnoser):

Before (class) After (struct)
Standalone Position 32 B 0 B
Class A position report 128 B / 2 allocations 112 B / 1 allocation

Versioning

Bumped to 1.0.0 via GitVersion (next-version: 0.31.0). PackageReleaseNotes documents the breaking changes. The package ships a single lib/net10.0/ assembly with XML documentation.

Verification

  • Build: 0 warnings / 0 errors.
  • Tests: 245 pass (net10.0).
  • Package: Ais.Net.Models.1.0.0.nupkg, single lib/net10.0/ target.

🤖 Generated with Claude Code

BREAKING: target .NET 10 only, dropping the net8.0 multi-targeting from the
previous minor release. CI updated to test net10.0 only and no longer installs
the .NET 8 SDK.

BREAKING: Position is now a `readonly record struct` (value type) instead of a
`record` class. This removes a heap allocation per decoded position: a
standalone Position is now 0 B (was 32 B), and a Class A position report drops
from 2 allocations / 128 B to 1 allocation / 112 B.

Bump to the 1.0 major version via GitVersion next-version, and document the
breaking changes in PackageReleaseNotes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3BkmohCNRYGY1RBKbNaCx
Copilot AI review requested due to automatic review settings July 23, 2026 11:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR prepares the 1.0.0 major release of Ais.Net.Models by moving the repo to .NET 10 only and reworking the core Position model into a value type to eliminate per-message heap allocations on decode paths.

Changes:

  • Drop multi-targeting and standardize projects/CI on net10.0 only.
  • Change Position from a record class to a readonly record struct and document the allocation rationale.
  • Update versioning (GitVersion) and refresh packaging/benchmarks to reflect the new runtime and type semantics.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
Solutions/Ais.Net.Models/Ais/Net/Models/Abstractions/Position.cs Converts Position to a readonly record struct and adds remarks explaining the allocation/perf motivation.
Solutions/Ais.Net.Models/Ais.Net.Models.csproj Switches to single-target net10.0 and updates PackageReleaseNotes for the 1.0 breaking changes.
Solutions/Ais.Net.Models.Specs/packages.lock.json Removes the net8.0 dependency set, leaving net10.0 as the sole locked framework.
Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj Switches the test project to single-target net10.0.
Solutions/Ais.Net.Models.Benchmarks/PositionBenchmarks.cs Updates benchmarks to reflect the new Position value type and exercises factory creation.
GitVersion.yml Updates next-version to 1.0 for the major release.
.github/workflows/build.yml Updates CI to test only net10.0 and removes the .NET 8 SDK install.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown

Test Results

245 tests  +245   245 ✅ +245   0s ⏱️ ±0s
  1 suites +  1     0 💤 ±  0 
  1 files   ±  0     0 ❌ ±  0 

Results for commit 8b7f86f. ± Comparison against base commit 585760b.

♻️ This comment has been updated with latest results.

- Seal the seven leaf AIS message records. This expresses their leaf-type intent
  for the major release and lets the JIT devirtualise equality/interface calls.
  It is allocation-neutral (message construction cost is unchanged).
- CleanVesselName now returns the input unchanged when it needs no '@'/space
  trimming and has no interior double-spaces to collapse, avoiding a string
  allocation for the common already-clean case (48 B -> 0 B, benchmark-confirmed).
- Add an already-clean name parameter to VesselNameBenchmarks to cover the fast path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3BkmohCNRYGY1RBKbNaCx
@HowardvanRooijen
HowardvanRooijen merged commit f996330 into main Jul 23, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants