Detect init-only properties, required members, and readonly structs/fields - #172
Merged
Merged
Conversation
…ields - Add IsInitOnly, IsRequired, IsWritable to PropertyInfoExtensions - Add IsRequired to MemberInfoExtensions and FieldInfoExtensions (new file) - Add IsReadOnlyStruct and IsFileLocal to TypeMetaDataExtensions - Add corresponding specs and update README Closes #157 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
dennisdoomen
force-pushed
the
dennisdoomen-init-only-required-readonly
branch
from
August 10, 2026 15:40
eca8eae to
6554cbd
Compare
dennisdoomen
enabled auto-merge (rebase)
August 10, 2026 15:42
added 2 commits
August 10, 2026 17:51
Resolve conflicts with PR #174 (nullable reference type metadata) by keeping both sets of additions in PropertyInfoExtensions.cs, FieldInfoExtensions.cs, their specs, and README.md.
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.
Summary
Implements approved API proposal #157 by adding reflection helpers to detect C# init-only properties,
requiredmembers, and readonly structs.PropertyInfoExtensionsIsInitOnly()— true when the setter's return parameter has theSystem.Runtime.CompilerServices.IsExternalInitrequired custom modifier (matched by full type name for cross-assembly/TFM safety, since PolySharp may polyfill this type on older TFMs).IsRequired()— true when the property is marked with the C# 11requiredmodifier (delegates toMemberInfoExtensions.IsRequired).IsWritable()— true only when the property has a setter and is not init-only (per the issue's explicit design decision thatinitis not "writable").MemberInfoExtensionsIsRequired(this MemberInfo member)— general-purpose check forSystem.Runtime.CompilerServices.RequiredMemberAttribute, matched by full name.FieldInfoExtensions(new file)IsRequired(this FieldInfo field)— same check, specific to fields.TypeMetaDataExtensionsIsReadOnlyStruct()— true for structs decorated withIsReadOnlyAttribute(matched by full name).IsFileLocal()— heuristic detection of C# 11file-local types via the compiler's metadata name-mangling pattern (<...>F{64-hex-hash}__{OriginalName}), documented as heuristic (same caveat as the existingIsRecordStruct).All attribute/modifier checks use full-name string matching rather than
typeof(...)comparisons, since these BCL types may not exist on older TFMs (net47, netstandard2.0/2.1) and could instead resolve to a PolySharp-polyfilled assembly, which would breakTypeequality comparisons.Tests
Added specs covering init-only vs. settable vs. get-only properties, required vs. non-required properties/fields, readonly vs. normal structs, and file-local vs. normal/anonymous types (including a
file-modified fixture type).Docs
Updated README's "How do I use it?" section to mention the new extension methods.
Validation
dotnet build src\Reflectify\Reflectify.csproj— succeeds for all 4 TFMs (net47, net6.0, netstandard2.0, netstandard2.1).dotnet test tests\Reflectify.Specs\Reflectify.Specs.csproj -f net8.0— 206/206 passing.Closes #157