Skip to content

Fix nullable implicit cast operator for string extensible enums - #12575

Open
Vishal Raj (vishalrajofficial) wants to merge 1 commit into
microsoft:mainfrom
vishalrajofficial:fix/nullable-extensible-enum-cast
Open

Vishal Raj (vishalrajofficial) wants to merge 1 commit into
microsoft:mainfrom
vishalrajofficial:fix/nullable-extensible-enum-cast

Conversation

@vishalrajofficial

Copy link
Copy Markdown

Description

Fixes #12572.

In PR #7967, a nullable implicit cast operator was added for string extensible enums:

public static implicit operator MyEnum?(string value) => value == null ? null : new MyEnum(value);

When evaluated, the conditional ternary operator's natural type resolves to MyEnum (struct) rather than MyEnum?. Consequently, the untyped null literal converts via the non-nullable implicit operator MyEnum(string value) with null, invoking the constructor with null and throwing an ArgumentNullException.

Fix

In ExtensibleEnumProvider.cs, cast the null branch to the nullable extensible enum type (Null.CastTo(Type.WithNullable(true))), emitting:

public static implicit operator MyEnum?(string value) => value == null ? (MyEnum?)null : new MyEnum(value);

This forces the ternary expression type to MyEnum?, evaluating directly to null without invoking the constructor.

Tests

  • Added unit test ConvertingNullStringToNullableExtensibleEnumDoesNotThrow in ExtensibleEnumTests.cs covering both variable assignment and method invocation with a null string.
  • Added AST assertion in EnumProviderTests.cs verifying the consequent expression is cast to Type.WithNullable(true).
  • Updated existing generated sample models in TestProjects/Local.

Cast the null branch of the ternary conditional expression to the nullable extensible enum type (Type.WithNullable(true)) so C# does not select the non-nullable implicit operator.

Fixes microsoft#12572

Signed-off-by: Vishal Raj <9031842908.vk@gmail.com>
Copilot AI balanced review requested due to automatic review settings November 13, 2026 05:24
@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 Nov 13, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
1 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues block the fix for null-string conversions in C# extensible enums.

No open issues 🎉

What changed in this PR

Fixes #12572 in the C# client generator by explicitly casting the null branch of string extensible enum conversions to the nullable enum type. This corrects the behavior introduced in #7967 so converting a null string returns null instead of throwing ArgumentNullException.

Changes:

  • Emit an explicitly typed nullable null in the conversion operator.
  • Add regression coverage for null-string assignment, method arguments, and the generated cast expression.
  • Update six generated sample models to reflect the fix.
File Description
packages/​http-client-csharp/​generator/​TestProjects/​Local/​Sample-TypeSpec/​src/​Generated/​Models/​ThingRequiredNullableLiteralString1.cs Updates the generated nullable conversion.
packages/​http-client-csharp/​generator/​TestProjects/​Local/​Sample-TypeSpec/​src/​Generated/​Models/​ThingOptionalLiteralString.cs Updates the generated nullable conversion.
packages/​http-client-csharp/​generator/​TestProjects/​Local/​Sample-TypeSpec/​src/​Generated/​Models/​StringExtensibleEnum.cs Applies the fix to the enum used by regression tests.
packages/​http-client-csharp/​generator/​TestProjects/​Local/​Sample-TypeSpec/​src/​Generated/​Models/​PreviewExtensibleChoice.cs Updates the generated nullable conversion.
packages/​http-client-csharp/​generator/​TestProjects/​Local/​Sample-TypeSpec/​src/​Generated/​Models/​LegacyExtensibleChoice.cs Updates the generated nullable conversion.
packages/​http-client-csharp/​generator/​TestProjects/​Local/​Sample-TypeSpec/​src/​Generated/​Models/​DaysOfWeekExtensibleEnum.cs Updates the generated nullable conversion.
packages/​http-client-csharp/​generator/​TestProjects/​Local.Tests/​ExtensibleEnumTests.cs Tests null-string assignment and method arguments.
packages/​http-client-csharp/​generator/​Microsoft.TypeSpec.Generator/​test/​Providers/​EnumProviders/​EnumProviderTests.cs Verifies the null branch casts to the nullable enum type.
packages/​http-client-csharp/​generator/​Microsoft.TypeSpec.Generator/​src/​Providers/​ExtensibleEnumProvider.cs Emits the explicit nullable cast in the null branch.

Review effort: Balanced

@vishalrajofficial

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

This branch has not been deployed

No deployments
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]: Nullable implicit operator on string extensible enums still throws for a null string

2 participants