Skip to content

fix(csharp): use full type names to avoid collision with standard library#23374

Open
Neokil wants to merge 1 commit intoOpenAPITools:masterfrom
Neokil:fix/csharp-test-type-name-collision
Open

fix(csharp): use full type names to avoid collision with standard library#23374
Neokil wants to merge 1 commit intoOpenAPITools:masterfrom
Neokil:fix/csharp-test-type-name-collision

Conversation

@Neokil
Copy link
Copy Markdown

@Neokil Neokil commented Mar 27, 2026

Description

When a model class shares a name with a type in the .NET standard library (for
example Attributes, which conflicts with System.Attribute), the generated
test code fails to compile because the unqualified type assertion is ambiguous.

Before (api_test.mustache):

var model = response.Ok();
Assert.IsType<Attributes>(model);  // ambiguous: Attributes vs System.Attribute

After:

var model = response.Ok();
Assert.IsType<MyPackage.Model.Attributes>(model);  // fully qualified, unambiguous

The fix conditionally uses the fully-qualified type name ({{packageName}}.{{modelPackage}}.{{{.}}}) when the response type is a model class. Primitive and other non-model return types are left as-is.

Changes

  • modules/openapi-generator/src/main/resources/csharp/libraries/generichost/api_test.mustache
    — use {{packageName}}.{{modelPackage}}.{{{.}}} for model return types inside Assert.IsType<>
  • modules/openapi-generator/src/test/resources/3_0/csharp/model-name-collision.yaml
    — new OpenAPI spec with a model named Attributes to reproduce the collision

How to reproduce

Generate a C# client from an OpenAPI spec that contains a model whose name
matches a .NET standard library class (e.g. Attributes, Exception, Task).
The generated *Tests files will fail to compile due to an ambiguous type reference
in Assert.IsType<>.

Generator

  • Language: C# (csharp)
  • Library: generichost
  • Template file: libraries/generichost/api_test.mustache

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR solves a reported issue, reference it using GitHub's linking syntax (e.g., having "fixes #123" present in the PR description)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Summary by cubic

Qualifies model return types in generated C# tests to avoid .NET type name collisions. Fixes compile errors when models share names with standard library types (e.g., Attributes).

  • Bug Fixes
    • In csharp/libraries/generichost/api_test.mustache, use {{packageName}}.{{modelPackage}}.{{{.}}} in Assert.IsType<> for model return types; non-model types unchanged.
    • Added 3_0/csharp/model-name-collision.yaml to reproduce and validate the fix.

Written for commit 08ef04a. Summary will update on new commits.

…tandard library name collisions

When a model class shares a name with a .NET standard library type (e.g.
`Attributes`), the generated `Assert.IsType<Attributes>(model)` call is
ambiguous and fails to compile. Use the fully-qualified type name
`{{packageName}}.{{modelPackage}}.{{{.}}}` for model return types so the
generated test code is unambiguous regardless of model naming.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Neokil
Copy link
Copy Markdown
Author

Neokil commented Mar 27, 2026

FYI @mandrean (2017/08) @shibayan (2020/02) @Blackclaws (2021/03) @lucamazzanti (2021/05) @iBicha (2023/07)

@Neokil Neokil changed the title fix(csharp): qualify model return types in generated tests to avoid s… fix(csharp): use full type names to avoid collision with standard library Mar 27, 2026
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 2 files


Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Add one-off context when rerunning by tagging @cubic-dev-ai with guidance or docs links (including llms.txt)
  • Ask questions if you need clarification on any suggestion

@devhl-labs
Copy link
Copy Markdown
Contributor

Thanks for this. I don't think we need a distinct yaml sample for this either, the petstore probably covers it already. Other than that, no real issues. Though we probably just shouldn't import System at all to avoid this.

@Chrimle
Copy link
Copy Markdown
Contributor

Chrimle commented Mar 29, 2026

Not a C# Dev really (Java). My two cents:
Core Language APIs should probably be "prioritized" in the sense that those should never use Fully-Qualified imports. That would leave any/all generated models named some already "reserved" name to be referenced using Fully-Qualified imports.

I think this makes the most sense for all languages and generators. Of course, this begs the question: does the generators know what class names are "reserved", in order to apply FQN when needed?

(So, doing fully-qualified on custom models - when they conflict - makes the most sense, and does not cause clutter except for those cases.)

@devhl-labs
Copy link
Copy Markdown
Contributor

I like that better. You wouldn't do fully qualified when they conflict, you would do it always.

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.

3 participants