Repository navigation
WeakString can only be set through Create [major] - #493
Open
matt-edmondson wants to merge 1 commit into
Open
matt-edmondson wants to merge 1 commit into
matt-edmondson wants to merge 1 commit into
Conversation
SemanticString.WeakString had a public init accessor, so
`uuid with { WeakString = "not a uuid" }` or `new Uuid { WeakString = "x" }`
built a value that never passed canonicalization or validation. For the
path types, `with` also carried over cached Parent and related values for
the old path.
The accessor is now protected init, and ISemanticString.WeakString is
get-only. Create sets the value through the cached setter delegate, which
now looks up the non-public accessor. A derived type can still set the
value from its own constructor. The path types are sealed, so with the
accessor closed nothing outside them can change a path's value through
`with` and leave the caches stale.
Breaking: callers that set WeakString in an object initializer or a `with`
expression must call Create instead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW2sHrLz9iC1cJzLLZy
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Fixes #310
What changed
SemanticString<T>.WeakStringis now{ get; protected init; }instead of{ get; init; }. Code outside the type hierarchy can no longer writeuuid with { WeakString = "not a uuid" }ornew Uuid { WeakString = "garbage" }, so the only way to get a value in is throughCreate, which canonicalizes and validates it.ISemanticString.WeakStringis now get-only.WeakStringSetter<TDest>delegate thatCreateuses (SemanticString.Create repeats type reflection on every call (~500 B and ~1.6 µs per value before any validator runs); cache per-type metadata #444) now looks up the non-public accessor (GetSetMethod(nonPublic: true)). A derived type can still set the value from its own constructor, which is what the existingSemanticStringExtensionsTests.TestSemanticStringdoes.AbsoluteDirectoryPath,AbsoluteFilePathandRelativeDirectoryPatharesealed, and nothing inside them useswith { WeakString = ... }. With the accessor closed, awithcopy always has the same value as its source, so the copiedParentand related caches stay correct. The types need no copy constructor.Breaking change
Removing a public accessor is a breaking API change, as the issue and its triage note, so the commit carries
[major]. A caller that setWeakStringin an object initializer or awithexpression must callCreate/As<T>()instead.dotnet packwith package validation onSemantics.Stringspasses with no new suppressions, because the change is the same across every target framework.Tests
WeakStringAccessTests:WeakStringhas no public setter onMySemanticString,Uuidor the three path types;ISemanticString.WeakStringis read-only;Createstill sets the value for aUuid, a plain semantic string and anAbsoluteDirectoryPath, including itsParent.Semantics.Stringschange reverted, the two accessor tests fail and the twoCreatetests pass. With the change they all pass.dotnet build -c Releasefinished with 0 warnings and 0 errors.dotnet test -c Releasehad 0 failures (1993 passed, the rest skipped).Generated by Claude Code