Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 27, 2026

  • Investigate the issue and understand the root cause
  • Write failing tests that reproduce the bug
  • Fix the issue by comparing serialized names instead of C# property names for discriminator de-duplication
  • Verify all related tests pass (1233 generator tests)
  • Run code review and address feedback
  • Add null checks for SerializedName as suggested in review

Root Cause Analysis

The bug occurs in ModelProvider.BuildProperties() where the check for duplicate discriminator properties only compared by C# property name (property.Name) instead of also checking the serialized name (property.SerializedName).

When the base model has a discriminator property with a different C# name than the derived model's discriminator property (but the same wire name like @odata.type), the check failed and the discriminator property was incorrectly added to the derived class.

Fix

Added a HashSet of base discriminator serialized names and extended the check to skip discriminator properties that match by either:

  1. C# property name (existing check)
  2. Serialized name (new check)

Added null checks for SerializedName as per code review feedback to ensure defensive coding practices.

Original prompt

This section details on the original issue you should resolve

<issue_title>[Bug]: Duplicate Discriminator Property in Derived Types</issue_title>
<issue_description>### Describe the bug

Description

The TypeSpec C# generator creates a duplicate OdataType property in derived classes when the base class already defines it as the discriminator. This causes CS0108 "hides inherited member" compiler warnings/errors.

Reproduction

In ContentUnderstandingSkill.cs (derived from SearchIndexerSkill):

Base class (SearchIndexerSkill.cs):

internal string OdataType { get; set; }

Derived class (ContentUnderstandingSkill.cs) incorrectly re-declares:

internal string OdataType { get; set; } = "#Microsoft.Skills.Util.ContentUnderstandingSkill";

The internal constructor also has a redundant parameter:

internal ContentUnderstandingSkill(
    string odataType,           // ? passed to base class
    ...,
    string odataType0)          // ? duplicate, assigned to local OdataType
    : base(odataType, ...)
{
    // ...
    OdataType = odataType0;     // ? This shouldn't exist
}

Expected Behavior

Derived types should NOT re-declare the discriminator property. The value should be set via the base class constructor only, which is already being done correctly in the public constructor:

public ContentUnderstandingSkill(...) 
    : base("#Microsoft.Skills.Util.ContentUnderstandingSkill", inputs, outputs)

Compiler Error

CS0108: 'ContentUnderstandingSkill.OdataType' hides inherited member 'SearchIndexerSkill.OdataType'. 
Use the new keyword if hiding was intended.

Root Cause

The TypeSpec definition likely has the @odata.type discriminator property appearing in both the base type and derived type definitions, or there's a conflict between the discriminator and a regular property with the same JSON name.

Affected Types

  • ContentUnderstandingSkill
  • ChatCompletionSkill
  • Potentially all derived skill types and any other polymorphic hierarchy with a discriminator property

Reproduction

Existing File with error : https://github.com/Azure/azure-sdk-for-net/blob/3df80e71cc22102f60910e9d188ca864ea18849d/sdk/search/Azure.Search.Documents/src/Generated/Models/ChatCompletionSkill.cs#L138C1-L139C1

Previous file: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/search/Azure.Search.Documents/src/Generated/Models/ChatCompletionSkill.cs

Checklist

<agent_instructions>This fix applies to packages\http-client-csharp</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits January 27, 2026 19:04
…ialized names

When a derived model has a discriminator property with a different C# name but the
same serialized name as the base model's discriminator, the property was incorrectly
being generated in the derived class, causing CS0108 "hides inherited member" warnings.

The fix adds a check for serialized names in addition to C# property names when
determining if a discriminator property should be skipped in derived types.

Co-authored-by: JonathanCrd <[email protected]>
Copilot AI changed the title [WIP] Fix duplicate OdataType property in derived types Fix duplicate discriminator property in derived types with matching serialized names Jan 27, 2026
Copilot AI requested a review from JonathanCrd January 27, 2026 19:09
@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 Jan 28, 2026
@github-actions
Copy link
Contributor

No changes needing a change description found.

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]: Duplicate Discriminator Property in Derived Types

2 participants