Skip to content

fix(http-client-csharp): override MRW *Core methods when external base declares them#11044

Merged
JoshLove-msft merged 2 commits into
microsoft:mainfrom
JoshLove-msft:joshlove/fix-11042-mrw-override-external-base
Jun 22, 2026
Merged

fix(http-client-csharp): override MRW *Core methods when external base declares them#11044
JoshLove-msft merged 2 commits into
microsoft:mainfrom
JoshLove-msft:joshlove/fix-11042-mrw-override-external-base

Conversation

@JoshLove-msft

@JoshLove-msft JoshLove-msft commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Fixes #11042

Problem

Models derived from an external/referenced MRW-generated base type (e.g. Azure.AI.Extensions.OpenAI types deriving from OpenAI's ResponseItem) generated PersistableModelCreateCore and the other serialization *Core methods as protected virtual instead of protected override. The compiler then reports CS0114 (hides inherited member ... add the override keyword).

Root cause

PR #11002 routes external InputModelTypes through SystemObjectModelProvider so derived models get a real ModelProvider base. However SystemObjectModelProvider.ShouldSkipDerivedSerializationMethodOverrides unconditionally returns true (introduced in #9862 for hand-authored ARM bases like ResourceData that do not follow the generated MRW pattern). Reusing it for all external bases forced derived models to hide rather than override even when the external base is itself MRW-generated and exposes the overridable *Core methods.

Fix

MrwSerializationTypeDefinition now decides whether to skip the derived overrides based on whether the external base actually participates in model-reader-writer serialization. When the base is a SystemObjectModelProvider, it inspects the wrapped framework/referenced type: if that type implements IJsonModel<T> or IPersistableModel<T>, it follows the generated MRW pattern and exposes the overridable *Core methods, so the derived model emits protected override. Otherwise existing behavior is preserved (bases that don't implement those interfaces, e.g. object/ResourceData, still emit virtual).

The check keys off the public model-reader-writer contract (the IJsonModel<T>/IPersistableModel<T> interfaces) rather than probing for protected *Core method names, so it doesn't depend on serialization implementation details.

Tests

Added regression tests in SystemObjectModelSerializationTests covering an external base that implements IJsonModel<T>, asserting the four *Core methods are emitted as override. Existing tests (object base -> virtual) remain unchanged. Full ClientModel suite (1435 tests) passes.

…e declares them

Issue microsoft#11042: derived models of an external/referenced MRW-generated base
(e.g. OpenAI's ResponseItem) generated PersistableModelCreateCore and the other
serialization *Core methods as `protected virtual` instead of `protected override`,
causing CS0114.

PR microsoft#11002 routed external models through SystemObjectModelProvider, whose
ShouldSkipDerivedSerializationMethodOverrides unconditionally returns true (added in
microsoft#9862 for hand-authored bases like ResourceData that lack the *Core methods). That
forced derived models to hide rather than override the base's *Core methods.

Now MrwSerializationTypeDefinition only skips the override when the wrapped framework
type does not declare all four generated *Core methods; when it does, derived models
correctly emit `protected override`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Jun 22, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jun 22, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-csharp@11044

commit: f2295b5

Replace the reflective *Core method-name probe with a check of whether the
external base type implements IJsonModel<T> or IPersistableModel<T>. This keys
off the public model-reader-writer contract instead of protected implementation
details, and drops the System.Reflection BindingFlags scan. The test's FakeMrwBase
now implements IJsonModel<T> to mirror a generated model.

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

Copy link
Copy Markdown
Contributor

No changes needing a change description found.

@JoshLove-msft JoshLove-msft added this pull request to the merge queue Jun 22, 2026
Merged via the queue into microsoft:main with commit cf1c72d Jun 22, 2026
29 checks passed
@JoshLove-msft JoshLove-msft deleted the joshlove/fix-11042-mrw-override-external-base branch June 22, 2026 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: PersistableModelCreateCore generated as protected virtual for a derived type

2 participants